1 module unde.games.dizzy.omega.main; 2 3 import derelict.sdl2.mixer; 4 import derelict.sdl2.sdl; 5 import derelict.opengl3.gl3; 6 import derelict.opengl3.gl; 7 8 import std.algorithm.comparison; 9 import std.algorithm.searching; 10 import std.concurrency; 11 import std.conv; 12 import std.format; 13 import std.functional; 14 import std.random; 15 import std.range.primitives; 16 import std.stdio; 17 import std.math; 18 19 import std.string; 20 import core.memory; 21 import unde.games.dizzy.omega.animations.bag_bug_anim; 22 import unde.games.dizzy.omega.animations.bucket; 23 import unde.games.dizzy.omega.animations.drop; 24 import unde.games.dizzy.omega.animations.fall_platform; 25 import unde.games.dizzy.omega.animations.ground_castle; 26 import unde.games.dizzy.omega.animations.ground_cave; 27 import unde.games.dizzy.omega.animations.ground_garden; 28 import unde.games.dizzy.omega.animations.light_drop; 29 import unde.games.dizzy.omega.animations.meteorite; 30 import unde.games.dizzy.omega.animations.platform1; 31 import unde.games.dizzy.omega.animations.platform4; 32 import unde.games.dizzy.omega.animations.explosure; 33 import unde.games.dizzy.omega.animations.sky_zaks; 34 import unde.games.dizzy.omega.animations.stalagmite; 35 import unde.games.dizzy.omega.animations.stone_00; 36 import unde.games.dizzy.omega.animations.stone_01; 37 import unde.games.dizzy.omega.animations.stone_02; 38 import unde.games.dizzy.omega.animations.stones; 39 import unde.games.dizzy.omega.animations.water; 40 import unde.games.dizzy.omega.animations.lava; 41 import unde.games.dizzy.omega.animations.statical; 42 import unde.games.dizzy.omega.animations.things_sweep_away_zaks; 43 import unde.games.dizzy.omega.bird; 44 import unde.games.dizzy.omega.bug; 45 import unde.games.dizzy.omega.grasshopper; 46 import unde.games.dizzy.omega.dialogs; 47 import unde.games.dizzy.omega.dizzy; 48 import unde.games.dizzy.omega.dog; 49 import unde.games.dizzy.omega.item; 50 import unde.games.dizzy.omega.rope; 51 import unde.games.dizzy.omega.rotatable; 52 import unde.games.dizzy.omega.save_load; 53 import unde.games.dizzy.omega.scene_loader; 54 import unde.games.dizzy.omega.star; 55 import unde.games.dizzy.omega.tree; 56 import unde.games.dizzy.omega.fish; 57 import unde.games.dizzy.omega.flame; 58 import unde.games.dizzy.omega.squid; 59 import unde.games.obj_loader; 60 import unde.games.object; 61 import unde.games.renderer; 62 import unde.games.collision_detector; 63 import unde.global_state; 64 import unde.keybar.lib; 65 import unde.tick; 66 67 enum STATE 68 { 69 NO_DIALOGS = 0, 70 INVENTORY = 1, 71 ENERGY_STAR = 2, 72 TOO_MANY_ITEMS = 3, 73 PIERCED_BY_STALAGMITE = 4, 74 PIERCED_BY_STALACTITE = 5, 75 HIT_BY_METEORITE = 6, 76 DISSOLVED_IN_ACID = 7, 77 BURNED_IN_LAVA = 8, 78 DAMAGED_BY_PIN = 9, 79 HIT_BY_ROCK = 10, 80 BURNED_IN_FLAME = 11, 81 CRUSHED_BY_PRESSURE = 12, 82 HELP = 99, 83 MARTIAN_AGRONOMIST_HELLO = 100, 84 MARTIAN_AGRONOMIST_HELLO1 = 101, 85 MARTIAN_AGRONOMIST_HELLO2 = 102, 86 MARTIAN_AGRONOMIST_HELLO3 = 103, 87 MARTIAN_AGRONOMIST_HELLO4 = 104, 88 MARTIAN_AGRONOMIST_HELLO5 = 105, 89 MARTIAN_AGRONOMIST_HELLO6 = 106, 90 LOOKING_BOOTH_MESSAGE = 200, 91 LOOKING_BOOTH = 201, 92 DIZZY_USED_KNIFE_MESSAGE = 300, 93 DIZZY_USED_KNIFE_ANIM = 301, 94 DIZZY_THROW_BRANCH_MESSAGE = 400, 95 DIZZY_THROW_BRANCH_ANIM = 401, 96 DIZZY_CUTS_ROPE_MESSAGE = 500, 97 DIZZY_CUTS_ROPE_ANIM = 501, 98 MARTIAN_ENGINEER_GET_AWAY = 600, 99 MARTIAN_AGRONOMIST_ROPE = 700, 100 MARTIAN_ENGINEER_TAKES_PLAYER = 800, 101 DIZZY_TIED_ROPE_MESSAGE = 900, 102 DIZZY_UNTIED_ROPE_MESSAGE = 901, 103 DIZZY_UNTIED_SHORT_ROPE_MESSAGE = 902, 104 MARTIAN_CHEMIST_HELLO = 1000, 105 MARTIAN_CHEMIST_HELLO1 = 1001, 106 MARTIAN_CHEMIST_HELLO2 = 1002, 107 MARTIAN_CHEMIST_HELLO3 = 1003, 108 MARTIAN_CHEMIST_HELLO4 = 1004, 109 MARTIAN_CHEMIST_HELLO5 = 1005, 110 DIZZY_DRINK_STUNNING_MESSAGE = 1100, 111 MARTIAN_AGRONOMIST_GIVES_BUCKET = 1200, 112 MARTIAN_AGRONOMIST_GIVES_BUCKET1 = 1201, 113 DIZZY_TRIES_FILL_BUCKET_MESSAGE = 1300, 114 DIZZY_THROW_METEORITE_MESSAGE = 1400, 115 DIZZY_FILL_BUCKET_MESSAGE = 1500, 116 DIZZY_TRIES_WATER_FLOWERS_MESSAGE = 1600, 117 DIZZY_COVERED_BUCKET_MESSAGE = 1700, 118 DIZZY_WATER_FLOWERS_MESSAGE = 1800, 119 MARTIAN_AGRONOMIST_THANKS = 1900, 120 MARTIAN_ENGINEER_RETURNS_PLAYER = 2000, 121 MARTIAN_ENGINEER_RETURNS_PLAYER1 = 2001, 122 MARTIAN_ENGINEER_RETURNS_PLAYER2 = 2002, 123 MARTIAN_ENGINEER_TAKES_BUCKET = 2100, 124 MARTIAN_ENGINEER_TAKES_BUCKET1 = 2101, 125 DIZZY_HOLD_BRANCH_UNDER_DROP = 2200, 126 MARTIAN_ENGINEER_GIVES_SPADE = 2300, 127 DIZZY_DIG_MESSAGE = 2400, 128 DIZZY_DIG_ANIM = 2401, 129 BAG_FOUND = 2500, 130 DIZZY_OPEN_DOOR = 2600, 131 DIZZY_DIG2_MESSAGE = 2700, 132 DIZZY_CATCH_GRASSHOPPER_MESSAGE = 2800, 133 MARTIAN_CHEMIST_NO_GRASSHOPPER = 2900, 134 MARTIAN_CHEMIST_NO_BIRD = 2901, 135 MARTIAN_CHEMIST_NO_GRASSHOPPERS_POISON = 2902, 136 MARTIAN_CHEMIST_THANK_YOU = 3000, 137 MARTIAN_CHEMIST_NEED_WATER_FROM_LIGHT_TREE_CAVE = 3100, 138 DIZZY_PUT_STONE_MESSAGE = 3200, 139 DIZZY_TRY_CATCH_BUG_MESSAGE = 3300, 140 DIZZY_CATCH_BUG_MESSAGE = 3400, 141 DIZZY_CATCH_FISH_MESSAGE = 3500, 142 DIZZY_CATCH_SQUID_MESSAGE = 3600, 143 MARTIAN_CHEMIST_NO_BUG = 3700, 144 MARTIAN_CHEMIST_NO_FISH = 3701, 145 MARTIAN_CHEMIST_NO_SQUID = 3702, 146 MARTIAN_CHEMIST_NO_BUGS_POISON = 3703, 147 MARTIAN_ENGINEER_RETURNS_BUCKET = 3800, 148 DIZZY_TRIES_TO_GET_WATER = 3900, 149 DIZZY_PUT_GROUND_TO_THE_BUCKET = 4000, 150 DIZZY_GET_LIGHT_WATER = 4100, 151 MARTIAN_CHEMIST_GIVES_PSYCHOTROPIC_SPRAY = 4200, 152 DIZZY_SPRAYED_BUG_MESSAGE = 4300, 153 DIZZY_SPRAYED_GRASSHOPPER_MESSAGE = 4400, 154 MARTIAN_ENGINEER_GIVES_WHISTLE = 4500, 155 DIZZY_DIG3_MESSAGE = 4600, 156 NOT_ALL_ITEMS_IN_THE_CASTLE_MESSAGE = 4700, 157 ROPE_NOT_IN_THE_CASTLE_MESSAGE = 4800, 158 DIZZY_WHISTLE_MESSAGE = 4900, 159 THINGS_SWEEP_AWAY_ZAKS_ANIM = 4901, 160 ZAKS_SAYS_FAREWELL_WORD = 4902, 161 STONES_CRASHES_MESSAGE = 4903, 162 TO_BE_CONTINUED_MESSAGE = 10000, 163 } 164 165 enum TEMP_MESSAGES 166 { 167 CANT_SAVE_IN_THE_MOVING, 168 CANT_SAVE_DURING_THE_QUEST, 169 SAVED, 170 NEGATIVE_LIVES, 171 PLAYS 172 } 173 174 immutable string[SC] screen_names; 175 immutable string[SC] screen_names_ru; 176 177 static this() 178 { 179 screen_names = 180 [ 181 SC(-1,0): "Entrance to cave", 182 SC(0, 0): "The landing place", 183 SC(1, 0): "The cave of light tree", 184 SC(1, 2): "The cave", 185 SC(1, 4): "The cave", 186 SC(2, 0): "The valley of death", 187 SC(3, 0): "The valley of death", 188 SC(4, 0): "The martian well", 189 SC(5, 0): "Under the open sky of Mars", 190 SC(6, 0): "Entrance to the cave of an extinct volcano", 191 SC(7, 0): "In the cave", 192 SC(8, 0): "In the cave", 193 SC(9, 0): "The first Martian", 194 SC(10,0): "Farmstead of the agronomist", 195 SC(10,2): "Barn of the agronomist", 196 SC(10,4): "The booth", 197 SC(11,0): "Garden", 198 SC(12,0): "Entrance to the secret laboratory", 199 SC(13,0): "The engineer", 200 SC(14,0): "Muzzle of the volcano", 201 SC(14,-1): "Muzzle of the volcano", 202 SC(15,0): "Chemical laboratory", 203 SC(16,0): "Cave corridor", 204 SC(17,0): "Corridor in the cave", 205 SC(18,0): "Exit from the cave of volcano", 206 SC(19,0): "Walls of the castle", 207 SC(19,1): "Walls of the castle", 208 SC(11,-1): "Descent into the cave", 209 SC(11,-2): "The mine", 210 SC(11,-3): "The bottom of mine", 211 SC(10,-3): "In shallow water", 212 SC( 9,-3): "In shallow water", 213 SC( 8,-3): "Afloat", 214 SC( 8,-4): "In the deep", 215 SC( 8,-5): "Dangerous deep", 216 SC( 8,-6): "Under thich layer of water", 217 SC( 8,-7): "Before entrance into the deep cave", 218 SC( 9,-7): "Lair of deep-sea dweller", 219 SC( 8,-8): "And can not see the bottom", 220 SC(12,-3): "Corridor in the deep of volcano", 221 SC(13,-3): "Corridor", 222 SC(14,-3): "Breakage", 223 SC(14,-4): "Fork", 224 SC(15,-4): "Blockage", 225 SC(14,-5): "It would seem the bottom", 226 SC(13,-5): "Again breakage", 227 SC(13,-6): "At entrance to the cave", 228 SC(12,-6): "Lair of shallow habitats", 229 SC(13,-7): "On the bottom ov volcano", 230 SC(14,-7): "At entrance to the castle of evil wizard", 231 SC(15,-7): "Travel gallery of Dizzy", 232 SC(15,-8): "Travel gallery of Dizzy", 233 SC(15,-9): "Aquarium and... Fire", 234 SC(16,-9): "Evil wizard Zaks", 235 ]; 236 237 screen_names_ru = 238 [ 239 SC(-1,0): "Вход в пещеру", 240 SC(0, 0): "Место посадки", 241 SC(1, 0): "Пещера сияющего дерева", 242 SC(1, 2): "Пещера", 243 SC(1, 4): "Пещера", 244 SC(2, 0): "Долина смерти", 245 SC(3, 0): "Долина смерти", 246 SC(4, 0): "Марсианский колодец", 247 SC(5, 0): "Под открытым небом Марса", 248 SC(6, 0): "Вход в пещеру потухшего вулкана", 249 SC(7, 0): "В пещере", 250 SC(8, 0): "В пещере", 251 SC(9, 0): "Первый марсианин", 252 SC(10,0): "Усадьба агронома", 253 SC(10,2): "Сарай агронома", 254 SC(10,4): "Будка", 255 SC(11,0): "Сад", 256 SC(12,0): "Вход в секретную лабораторию", 257 SC(13,0): "Инженер", 258 SC(14,0): "Жерло вулкана", 259 SC(14,-1): "Жерло вулкана", 260 SC(15,0): "Химическая лаборатория", 261 SC(16,0): "Пещерный коридор", 262 SC(17,0): "Коридор пещерный", 263 SC(18,0): "Выход из пещеры вулкана", 264 SC(19,0): "Стены замка", 265 SC(19,1): "Стены замка", 266 SC(11,-1): "Спуск в пещеру", 267 SC(11,-2): "Шахта", 268 SC(11,-3): "Дно шахты", 269 SC(10,-3): "На мелководье", 270 SC( 9,-3): "На мелководье", 271 SC( 8,-3): "На поверхности", 272 SC( 8,-4): "В глубине", 273 SC( 8,-5): "Опасная глубина", 274 SC( 8,-6): "Под толстым слоем воды", 275 SC( 8,-7): "У входа в глубинную пещеру", 276 SC( 9,-7): "Логово глубоководного обитателя", 277 SC( 8,-8): "И не видно дна", 278 SC(12,-3): "Коридор в глубине вулкана", 279 SC(13,-3): "Коридор", 280 SC(14,-3): "Обрыв", 281 SC(14,-4): "Развилка", 282 SC(15,-4): "Завал", 283 SC(14,-5): "Казалось бы дно", 284 SC(13,-5): "Снова обрыв", 285 SC(13,-6): "У входа в пещеру", 286 SC(12,-6): "Логово мелководных обитателей", 287 SC(13,-7): "На дне вулкана", 288 SC(14,-7): "У входа в замок злого волшебника", 289 SC(15,-7): "Галерея путешествий Диззи", 290 SC(15,-8): "Галерея путешествий Диззи", 291 SC(15,-9): "Аквариум и... Огонь", 292 SC(16,-9): "Злой волшебник - Закс", 293 ]; 294 } 295 296 bool in_the_castle(Item item) 297 { 298 return item.inventory || 299 item.x >= (15*30.0 - 15.0) && 300 item.y <= (-7*17.0 + 8.5); 301 } 302 303 class DizzyOmega:MainGameObject 304 { 305 const (ObjFile)*[10] energy_star; 306 Item[] items; 307 size_t[] inventory; 308 int max_items = 3; 309 GLuint[string] textures; 310 Star[] stars; 311 Tree[] trees; 312 StaticGameObject[] animations; 313 Dialogs dialogs; 314 Star star0; 315 Star star1; 316 Item blanket; 317 Item branch; 318 Item player; 319 Item rope; 320 Item baloon; 321 Item stunning_drink; 322 Item bottle; 323 Item bucket; 324 Item bucket_of_water; 325 Item bucket_of_ice; 326 Item bucket_covered; 327 Item meteorite; 328 Item spade; 329 Item light_branch; 330 Item short_rope; 331 Item stone1; 332 Item stone2; 333 Item stone3; 334 Item bag; 335 Item key; 336 Item pressprot; 337 Item bugs_poison; 338 Item grasshoppers_poison; 339 Item grasshopper_item; 340 Item bird_item; 341 Item bug_item; 342 Item nettle; 343 Item fish_item; 344 Item fish_rod; 345 Item squid_item; 346 Item bucket_with_ground; 347 Item bucket_with_light_water; 348 Item psychotropic_spray; 349 Item whistle; 350 Item umbrella; 351 Item kitchen_knife; 352 Bucket bucket_anim; 353 Rope rope1; 354 Rope rope2; 355 Rope rope3; 356 GroundCastle ground_castle; 357 GroundCave ground_cave; 358 GroundGarden ground_garden; 359 Stones stones; 360 Rotatable door; 361 Rotatable zaks; 362 int rope_state; 363 364 Mix_Music *energy_minus; 365 Mix_Music *energy_plus; 366 long energy_start_tick = -1; 367 bool music; 368 Mix_Music*[] musics; 369 float[] music_len; 370 string[] music_name; 371 long music_start_tick = -1; 372 int track; 373 374 //float stopped_music_position; 375 MUSIC_STATE music_state; 376 377 enum MUSIC_STATE 378 { 379 MUSIC, 380 ENERGY_PLUS, 381 ENERGY_MINUS, 382 } 383 384 GLuint[SC] screen_lists; 385 386 enum LANG 387 { 388 EN = 0, 389 RU = 1, 390 MAX= 1, 391 } 392 393 LANG lang; 394 395 immutable string[string] names; 396 immutable string[string] names_ru; 397 398 string[TEMP_MESSAGES] temp_messages; 399 string[TEMP_MESSAGES] temp_messages_ru; 400 TEMP_MESSAGES temp_message; 401 string temp_message_str; 402 long temp_message_frame_from; 403 long temp_message_frame_to; 404 405 int reinit_draw; 406 bool[string] done_dialogs; 407 408 Random rnd; 409 410 Dizzy the_hero; 411 BagBugAnim bag_bug_anim; 412 Dog dog; 413 Rotatable martian_engineer; 414 Explosure explosure; 415 Grasshopper grasshopper; 416 Bird bird; 417 Bug bug; 418 Fish fish; 419 Squid squid; 420 ThingsSweepAwayZaks things_sweep_away_zaks; 421 Water water3; 422 423 int dizzy_used_knife_quest_state = -1; 424 int dizzy_throw_branch_quest_state = -1; 425 int dizzy_cuts_rope_quest_state = -1; 426 int dizzy_live_after_explosure_quest_state = -1; 427 int dizzy_water_flowers_state = -1; 428 int wait_meteorite = -1; 429 int wait_meteorite2 = -1; 430 431 struct BranchQuestVariables { 432 int st; 433 float degree; 434 float x, y; 435 float dx, dy; 436 } 437 438 Tid sl_tid; 439 440 BranchQuestVariables branch_quest_variables; 441 442 this(GlobalState gs) 443 { 444 textures["font"] = load_texture("models/dizzy/font.png", true, 5); 445 446 toGame(gs); 447 loadingMessage(gs); 448 449 foreach(model; ["dizzy", "dizzy-cosmonaut", "kitchen-knife", "blanket", 450 "stone", "bag", "fish-rod", "rocket", "zaks-face", 451 "light-drop", "drop", "branch", "bug", 452 "dog", "martian-engineer", "martian-chemist", 453 "player", 454 "rope", "before-explosure", 455 "after-explosure-down", "after-explosure-up", 456 "bomb", "baloon", "explosure", 457 "stunning-drink", "bottle", 458 "umbrella", "bucket", "bucket-of-water", 459 "bucket-of-ice", "bucket-covered", 460 "bucket-out-water", "bucket-water", 461 "meteorite", "spade", "light-branch", 462 "short-rope", 463 "oiler", "grenade", 464 "branch-of-tree-full", "branch-of-tree-cut", 465 "branch-on-tree", 466 "stalagmite", "fall-platform-0", 467 "platform1", "platform2", 468 "ground-garden", "ground-garden-1", "ground-garden-2", 469 "ground-garden-3", 470 "cave-water", "cave-water-2", "cave-water-3", 471 "aquarium", "door", 472 "bird", "flame", "bird-item", 473 "grasshoppers-poison", "bugs-poison", 474 "key", "pressure-protection", 475 "dynamite-grand", "nettle", 476 "lava-bubble", "platform4", 477 "ground-cave", "ground-cave-1", 478 "fish-item", "squid-item", 479 "psychotropic-spray", "whistle", 480 "zaks", "ground-castle", "ground-castle-1", 481 "stones-1", "stones-2"]) 482 { 483 models[model] = cast(shared) load_objfile(format("models/%s.obj", model)); 484 } 485 486 models["stone1"] = models["stone"]; 487 models["stone2"] = models["stone"]; 488 models["stone3"] = models["stone"]; 489 models["bucket-with-ground"] = models["bucket"]; 490 models["bucket-with-light-water"] = models["bucket"]; 491 492 models["solid"] = cast(shared) load_objfile("models/scene-solid.obj"); 493 models["water"] = cast(shared) load_objfile("models/scene-01-water.obj"); 494 models["clouds"] = cast(shared) load_objfile("models/scene-01-clouds.obj"); 495 models["dangers"] = cast(shared) load_objfile("models/scene-dangers.obj"); 496 models["temp-solid"] = cast(shared) load_objfile("models/temp-solid.obj"); 497 498 foreach(i; 0..14) 499 { 500 models[format("tree-%02d", i)] = 501 cast(shared) load_objfile(format("models/mars-tree-%02d.obj", i)); 502 } 503 504 models["stone-00"] = cast(shared) load_objfile("models/stone-00.obj"); 505 models["stone-01"] = cast(shared) load_objfile("models/stone-01.obj"); 506 models["stone-02"] = cast(shared) load_objfile("models/stone-02.obj"); 507 508 models["meteorite-01"] = cast(shared) load_objfile("models/meteorite-01.obj"); 509 models["meteorite-02"] = cast(shared) load_objfile("models/meteorite-02.obj"); 510 models["meteorite-03"] = cast(shared) load_objfile("models/meteorite-03.obj"); 511 512 models["small-stone-00"] = cast(shared) load_objfile("models/small-stone-00.obj"); 513 514 for (int i=0; i < 10; i++) 515 { 516 models["star-"~i.to!(string)] = cast(shared) load_objfile(("models/energy-star-"~i.to!(string)~".obj")); 517 } 518 519 for (int i=0; i < 5; i++) 520 { 521 models["fish-"~i.to!(string)] = cast(shared) load_objfile(("models/fish-"~i.to!(string)~".obj")); 522 } 523 524 for (int i=0; i < 11; i++) 525 { 526 models["squid-"~i.to!(string)] = cast(shared) load_objfile(("models/squid-"~i.to!(string)~".obj")); 527 } 528 529 for (int i=0; i < 4; i++) 530 { 531 models["flame-"~i.to!(string)] = cast(shared) load_objfile(("models/flame-"~i.to!(string)~".obj")); 532 } 533 534 for (int i=0; i < 6; i++) 535 { 536 models["grasshopper-"~i.to!(string)] = cast(shared) load_objfile(("models/grasshopper-"~i.to!(string)~".obj")); 537 } 538 539 collision_objects["solid"] = null; 540 scene_to_collision_object (cast(ObjFile*) models["solid"], collision_objects["solid"]); 541 collision_objects["water"] = null; 542 scene_to_collision_object (cast(ObjFile*) models["water"], collision_objects["water"]); 543 collision_objects["clouds"] = null; 544 scene_to_collision_object (cast(ObjFile*) models["clouds"], collision_objects["clouds"]); 545 collision_objects["dangers"] = null; 546 scene_to_collision_object (cast(ObjFile*) models["dangers"], collision_objects["dangers"]); 547 collision_objects["temp-solid"] = null; 548 scene_to_collision_object (cast(ObjFile*) models["temp-solid"], collision_objects["temp-solid"]); 549 550 models.remove("solid"); 551 models.remove("water"); 552 models.remove("clouds"); 553 models.remove("dangers"); 554 models.remove("temp-solid"); 555 556 models["bug-solid"] = cast(shared) load_objfile("models/bug-collisions.obj"); 557 collision_objects["bug-solid"] = null; 558 scene_to_collision_object (cast(ObjFile*) models["bug-solid"], collision_objects["bug-solid"]); 559 560 models["grasshopper-solid"] = cast(shared) load_objfile("models/grasshopper-collisions.obj"); 561 collision_objects["grasshopper-solid"] = null; 562 scene_to_collision_object (cast(ObjFile*) models["grasshopper-solid"], collision_objects["grasshopper-solid"]); 563 564 models["grasshopper-solid-1"] = cast(shared) load_objfile("models/grasshopper-collisions-1.obj"); 565 collision_objects["grasshopper-solid-1"] = null; 566 scene_to_collision_object (cast(ObjFile*) models["grasshopper-solid-1"], collision_objects["grasshopper-solid-1"]); 567 568 models["underground-solid"] = cast(shared) load_objfile("models/underground-collisions.obj"); 569 collision_objects["underground-solid"] = null; 570 scene_to_collision_object (cast(ObjFile*) models["underground-solid"], collision_objects["underground-solid"]); 571 572 collision_objects["solid"]["BranchForBreak"] = collision_objects["temp-solid"]["BranchForBreak"]; 573 collision_objects["solid"]["Platform1"] = collision_objects["temp-solid"]["Platform1"]; 574 collision_objects["solid"]["Platform2"] = collision_objects["temp-solid"]["Platform2"]; 575 collision_objects["solid"]["BeforeExplosure1"] = collision_objects["temp-solid"]["BeforeExplosure1"]; 576 collision_objects["solid"]["BeforeExplosure2"] = collision_objects["temp-solid"]["BeforeExplosure2"]; 577 collision_objects["solid"]["GroundGarden"] = collision_objects["temp-solid"]["GroundGarden"]; 578 collision_objects["solid"]["Stone2"] = collision_objects["temp-solid"]["Stone2"]; 579 collision_objects["solid"]["Platform4"] = collision_objects["temp-solid"]["Platform4"]; 580 collision_objects["solid"]["Wall1"] = collision_objects["temp-solid"]["Wall1"]; 581 582 items = [kitchen_knife = new Item(this, [93.7, -4.9, 0.0], "kitchen-knife"), 583 stone1 = new Item(this, [223.1, 2.9, 0.0], "stone1"), 584 fish_rod = new Item(this, [309.0, 34.5, 3.0], "fish-rod"), 585 branch = new Item(this, [330.0, 34.0, 0.0], "branch"), 586 light_branch = new Item(this, [390.0, 34.0, 0.0], "light-branch"), 587 player = new Item(this, [120.0, 34.0, 0.0], "player"), 588 rope = new Item(this, [280.0, 34.0, 0.0], "rope"), 589 baloon = new Item(this, [433.0, -22.0, 0.0], "baloon"), 590 stunning_drink = new Item(this, [450.0, 34.0, 0.0], "stunning-drink"), 591 bottle = new Item(this, [450.0, 34.0, 0.0], "bottle"), 592 umbrella = new Item(this, [511.5, -6.6, -2.6], "umbrella"), 593 stone2 = new Item(this, [334.6, 34.0, 0.0], "stone2"), 594 stone3 = new Item(this, [422.0, -98.4, 0.0], "stone3"), 595 bucket = new Item(this, [280.0, 34.0, 0.0], "bucket"), 596 bucket_of_water = new Item(this, [280.0, 34.0, 0.0], "bucket-of-water"), 597 bucket_of_ice = new Item(this, [280.0, 34.0, 0.0], "bucket-of-ice"), 598 bucket_covered = new Item(this, [280.0, 34.0, 0.0], "bucket-covered"), 599 bucket_with_ground = new Item(this, [280.0, 34.0, 0.0], "bucket-with-ground"), 600 bucket_with_light_water = new Item(this, [280.0, 34.0, 0.0], "bucket-with-light-water"), 601 blanket = new Item(this, [210.7, -6.4, 0.0], "blanket"), 602 meteorite = new Item(this, [150.0, 34.0, 0.0], "meteorite"), 603 spade = new Item(this, [390.0, 34.0, 0.0], "spade"), 604 short_rope = new Item(this, [360.0, 34.0, 0.0], "short-rope"), 605 new Item(this, [-30.1, -7.3, 0.0], "oiler"), 606 new Item(this, [-40.6, -2.6, 0.0], "grenade"), 607 bag = new Item(this, [262.8, -57.5, 0.0], "bag"), 608 grasshoppers_poison = new Item(this, [392.2, -99.0, 0.0], "grasshoppers-poison"), 609 bugs_poison = new Item(this, [231.9, -71.9, 0.0], "bugs-poison"), 610 key = new Item(this, [439.0, -72.7, 0.0], "key"), 611 pressprot = new Item(this, [465.9, 34.0, 0.0], "pressure-protection"), 612 new Item(this, [453.2, -116.0, 0.0], "dynamite-grand"), 613 nettle = new Item(this, [20.5, 33.8, 0.0], "nettle"), 614 grasshopper_item = new Item(this, [20.5, 80.0, 0.0], "grasshopper-0"), 615 bird_item = new Item(this, [150.0, 80.0, 0.0], "bird-item"), 616 bug_item = new Item(this, [150.0, 80.0, 0.0], "bug"), 617 fish_item = new Item(this, [150.0, 80.0, 0.0], "fish-item"), 618 squid_item = new Item(this, [150.0, 80.0, 0.0], "squid-item"), 619 psychotropic_spray = new Item(this, [150.0, 80.0, 0.0], "psychotropic-spray"), 620 whistle = new Item(this, [150.0, 80.0, 0.0], "whistle"),]; 621 622 stars = [new Star(this, [21.6, -3.0, 0.0]), 623 new Star(this, [84.3, -3.4, 0.0]), 624 new Star(this, [189.0, 2.5, 0.0]), 625 new Star(this, [273.0, 3.0, 0.0]), 626 new Star(this, [270.0, -5.2, 0.0]), 627 new Star(this, [295.0, -1.2, 0.0]), 628 new Star(this, [293.2, 38.4, 3.0]), 629 new Star(this, [326.5, 2.24, -0.9]), 630 new Star(this, [357.8, 3.9, 0.9]), 631 new Star(this, [402.7, -2.3, 0.0]), 632 star0 = new Star(this, [418.7, 5.2, 0.0]), 633 new Star(this, [436.0, 5.0, 0.0]), 634 new Star(this, [466.4, 1.7, 0.0]), 635 new Star(this, [511.5, -6.6, 0.0]), 636 new Star(this, [572.8, 1.5, 0.0]), 637 new Star(this, [277.5, -58.0, 0.0]), 638 new Star(this, [244.8, -74.8, 0.0]), 639 new Star(this, [245.5, -124.5, 0.0]), 640 new Star(this, [242.2, -132.8, 0.0]), 641 new Star(this, [402.2, -56.9, 0.0]), 642 new Star(this, [419.8, -54.7, 0.0]), 643 new Star(this, [427.8, -87.7, 0.0]), 644 new Star(this, [353.7, -99.3, 0.0]), 645 new Star(this, [347.3, -108.3, 0.0]), 646 new Star(this, [460.7, -121.8, 0.0]), 647 new Star(this, [444.7, -137.8, 0.0]), 648 new Star(this, [484.7, -158.9, 0.0]), 649 star1 = new Star(this, [29.9, 34.8, 0.0]), 650 new Star(this, [22.9, 69.8, 0.0]),]; 651 652 trees = [new Tree(this, 2.7, [4.0, -7.5, 0.7], 0), 653 new Tree(this, 2.47, [97.7, -2.7, 0.7], 1), 654 new Tree(this, 4.44, [108.0, -5.5, 2.1], 2), 655 new Tree(this, 3.0, [114.0, -5.9, 0.9], 3), 656 new Tree(this, 1.9, [115.0, 0.2, 1.6], 4), 657 new Tree(this, 1.9, [116.6, 0.3, -1.6], 5), 658 new Tree(this, 2.54, [119.2, 0.2, 2.1], 6), 659 new Tree(this, 4.1, [122.0, -6.3, -2.0], 7), 660 new Tree(this, 3.5, [128.0, -3.1, 1.4], 8), 661 new Tree(this, 3.2, [137.2, -5.3, 0.7], 9), 662 new Tree(this, 3.5, [150.0, -4.9, 1.6], 10), 663 new Tree(this, 3.0, [158.3, -4.5, 1.1], 11), 664 new Tree(this, 3.3, [169.7, -6.1, 1.6], 12), 665 new Tree(this, 3.1, [180.0, -6.5, 0.7], 13), 666 ]; 667 668 the_hero = new Dizzy(this, [-7.0, -7.2, 0.0]); 669 670 bag_bug_anim = new BagBugAnim(this); 671 672 rnd = Random(28); 673 674 animations = [new Stone00(this, the_hero), 675 new Stone01(this, the_hero), 676 new Stone02(this, the_hero), 677 new SkyZaks(this, the_hero), 678 new Stalagmite(this, the_hero), 679 new Meteorite(this, the_hero, bird, rnd), 680 new LightDrop(this), 681 new Drop(this, 197.4, 2.1, 1.8, -6.2, -1.6, 0), 682 new Drop(this, 305.5, 8.4, 8.3, 5.1, 3.9, 0), 683 new Drop(this, 306.8, 8.4, 8.3, 5.6, 3.9, 100), 684 new Drop(this, 308.2, 8.4, 8.3, 5.6, 3.9, 150), 685 new Drop(this, 311.3, 8.4, 8.3, 5.6, 3.9, 225), 686 new Drop(this, 454.8, 0.8, 0.6, -6.3, 1.9, 0), 687 new Drop(this, 458.9, 0.8, 0.6, -2.0, 1.9, 50), 688 new Drop(this, 461.9, 0.8, 0.6, -2.0, 1.9, 250), 689 new Drop(this, 457.3, -2.8, -3.0, -6.3, 1.9, 280), 690 new Drop(this, 458.9, -2.8, -3.0, -6.3, 1.9, 220), 691 new Drop(this, 460.6, -2.8, -3.0, -6.3, 1.9, 120), 692 new Drop(this, 461.6, -2.8, -3.0, -6.3, 1.9, 180), 693 new Drop(this, 308.6, -48.5, -48.8, -55.2, 2.1, 0), 694 new Drop(this, 298.0, -48.0, -48.2, -55.2, 2.1, 100), 695 new Drop(this, 291.7, -48.3, -48.6, -55.2, 2.1, 87), 696 new Drop(this, 273.5, -46.6, -46.8, -55.2, 2.1, 24), 697 new Drop(this, 267.0, -48.0, -48.3, -55.2, 2.1, 250), 698 new Drop(this, 260.4, -50.1, -50.5, -55.2, 2.1, 180), 699 new FallPlatform(this, the_hero, [247.3, 2.1, 0.0], 0), 700 bug = new Bug(this, [252.0, -5.6, 0.0], "bug-solid"), 701 grasshopper = new Grasshopper(this, [20.6, 60.5, 0.0], "grasshopper-solid", "grasshopper-solid-1", the_hero), 702 dog = new Dog(this, [362.0, -3.5, 0.0], [359.5, -2.4, 3.0], -5.1, 20, 0.5, the_hero), 703 martian_engineer = new Rotatable(this, [401.8, 2.7, 0.0], 90.0, "martian-engineer"), 704 new Rotatable(this, [463.2, 1.7, 2.1], 0.0, "martian-chemist"), 705 new Platform1(this, [418.5, 4.6, 0.0]), 706 explosure = new Explosure(this, [416.4, -20.7, 0.0], [425.4, -16.7, 0.0], [412.4, -20.5, 0.0], the_hero), 707 bucket_anim = new Bucket(this), 708 ground_garden = new GroundGarden(this), 709 stones = new Stones(this), 710 bird = new Bird(this, [318.7, -36.2, 0.0], 332.7, the_hero), 711 new Fish(this, [232.8, -85.9, 0.0], 232.8, 240.8, 1.0, 1.0), 712 new Fish(this, [348.4, -106.0, 0.0], 348.4, 366.9, 0.5, 1.0), 713 new Fish(this, [352.0, -106.0, 0.0], 348.4, 366.9, 0.7, 0.8), 714 fish = new Fish(this, [366.9, -106.0, 0.0], 348.4, 366.9, 0.4, 1.2), 715 new Fish(this, [459.0, -149.5, 4.0], 450.0, 468.0, 1.5, 0.25), 716 squid = new Squid(this, [276.0, -113.0, 0.0], -120.0), 717 new Water(this, "cave-water", -55.5), 718 new Water(this, "cave-water-2", -106.01), 719 water3 = new Water(this, "cave-water-3", -160.0), 720 new Statical(this, "aquarium"), 721 door = new Rotatable(this, [17.3, 2.0, 2.0], 0.0, "door"), 722 new Flame(this, [458.5, -157.3, 1.0], 0), 723 new Flame(this, [451.8, -157.3, 1.0], 2), 724 new Lava(this, [422.3, -125.4, -2.5], [429.3, -124.4, 2.5], rnd), 725 new Platform4(this, [29.6, 34.4, 0.0]), 726 ground_cave = new GroundCave(this), 727 ground_castle = new GroundCastle(this), 728 zaks = new Rotatable(this, [489.0, -159.1, 0.0], 0.0, "zaks"), 729 things_sweep_away_zaks = new ThingsSweepAwayZaks(this), 730 ]; 731 732 rope1 = new Rope(root, [418.1, 1.3, 0.7], [416.9, 1.3, 0.0], -13.0, 30, 0.5, 3); 733 rope2 = new Rope(root, [245.0, 2.2, 0.7], [246.2, 2.2, 0.0], -5.0, 7, 0.5, 3); 734 rope3 = new Rope(root, [331.2, -13.7, 0.7], [333.0, -13.7, 0.0], -53.1, 70, 0.5, 3); 735 736 textures["live"] = load_texture("models/dizzy/dizzy-live.png"); 737 textures["energy"] = load_texture("models/dizzy/energy.png"); 738 739 names = 740 [ 741 "kitchen-knife": "Kitchen Knife", 742 "blanket": "Quilted Blanket", 743 "stone1": "Stone", 744 "stone2": "Stone", 745 "stone3": "Stone", 746 "fish-rod": "Fish Rod", 747 "branch": "Branch", 748 "light-branch": "Light Branch", 749 "player": "Player", 750 "rope": "Rope", 751 "baloon": "Baloon", 752 "stunning-drink": "Stunning drink", 753 "bottle": "Bottle", 754 "umbrella": "Umbrella", 755 "bucket": "Bucket", 756 "bucket-of-water": "Bucket Of Water", 757 "bucket-of-ice": "Bucket Of Ice", 758 "bucket-covered": "Covered Bucket of Water", 759 "bucket-with-ground": "Bucket with ground", 760 "bucket-with-light-water": "Bucket with light water", 761 "meteorite": "Meteorite", 762 "spade": "Spade", 763 "short-rope": "Short Rope", 764 "oiler": "Oiler", 765 "grenade": "Hand Grenade", 766 "grasshoppers-poison": "Grasshopper Poison", 767 "bugs-poison": "Bug Poison", 768 "key": "Key", 769 "pressure-protection": "Pressure Protection", 770 "dynamite-grand": "Dynamite Grand", 771 "nettle": "Nettle", 772 "grasshopper-0": "Grasshopper", 773 "bird-item": "Bird", 774 "bug": "Bug", 775 "fish-item": "Fish", 776 "squid-item": "Squid", 777 "psychotropic-spray": "Psychotropic Spray", 778 "whistle": "Whistle", 779 ]; 780 781 names_ru = 782 [ 783 "kitchen-knife": "Кухонный нож", 784 "blanket": "Ватное Одеяло", 785 "stone1": "Камень", 786 "stone2": "Камень", 787 "stone3": "Камень", 788 "fish-rod": "Удочка", 789 "branch": "Ветка", 790 "light-branch": "Сияющая ветка", 791 "player": "Плеер", 792 "rope": "Верёвка", 793 "baloon": "Воздушный шар", 794 "stunning-drink": "Напиток \"Сногсшибающий\"", 795 "bottle": "Бутылка", 796 "umbrella": "Зонт", 797 "bucket": "Ведро", 798 "bucket-of-water": "Ведро воды", 799 "bucket-of-ice": "Ведро льда", 800 "bucket-covered": "Накрытое Ведро с Водой", 801 "bucket-with-ground": "Ведро с землёй", 802 "bucket-with-light-water": "Ведро с сияющей водой", 803 "meteorite": "Метеорит", 804 "spade": "Лопата", 805 "short-rope": "Короткая Верёвка", 806 "oiler": "Маслёнка", 807 "grenade": "Ручная Граната", 808 "grasshoppers-poison": "Отрава для кузнечиков", 809 "bugs-poison": "Отрава для жуков", 810 "key": "Ключ", 811 "pressure-protection": "Защита от давления", 812 "dynamite-grand": "Динамит большой", 813 "nettle": "Сачок", 814 "grasshopper-0": "Кузнечик", 815 "bird-item": "Птичка", 816 "bug": "Жук", 817 "fish-item": "Рыба", 818 "squid-item": "Кальмар", 819 "psychotropic-spray": "Психотропный Препарат", 820 "whistle": "Свисток", 821 ]; 822 823 temp_messages = 824 [ 825 TEMP_MESSAGES.CANT_SAVE_IN_THE_MOVING: "Can't save in the moving", 826 TEMP_MESSAGES.CANT_SAVE_DURING_THE_QUEST: "Can't save during the quest", 827 TEMP_MESSAGES.SAVED: "Saved", 828 TEMP_MESSAGES.NEGATIVE_LIVES: "Negative amount of lives", 829 TEMP_MESSAGES.PLAYS: "Plays", 830 ]; 831 832 temp_messages_ru = 833 [ 834 TEMP_MESSAGES.CANT_SAVE_IN_THE_MOVING: "Не могу сохранить в движении", 835 TEMP_MESSAGES.CANT_SAVE_DURING_THE_QUEST: "Не могу сохранить во время квеста", 836 TEMP_MESSAGES.SAVED: "Сохранено", 837 TEMP_MESSAGES.NEGATIVE_LIVES: "Отрицательное число жизней", 838 TEMP_MESSAGES.PLAYS: "Звучит", 839 ]; 840 841 dialogs = new Dialogs(this); 842 843 /*if (scene) { 844 get_bounding_box(scene, &scene_min, &scene_max); 845 scene_center.x = (scene_min.x + scene_max.x) / 2.0f; 846 scene_center.y = (scene_min.y + scene_max.y) / 2.0f; 847 scene_center.z = (scene_min.z + scene_max.z) / 2.0f; 848 } 849 else 850 throw new Exception(format("Error while aiImportFile"));*/ 851 852 energy_minus = Mix_LoadMUS("sounds/energy-minus.ogg"); 853 if(!energy_minus) { 854 writefln("Mix_LoadMUS 'sounds/energy_minus.ogg': %s", Mix_GetError().to!(string)()); 855 } 856 857 energy_plus = Mix_LoadMUS("sounds/energy-plus.ogg"); 858 if(!energy_plus) { 859 writefln("Mix_LoadMUS 'sounds/energy_plus.ogg': %s", Mix_GetError().to!(string)()); 860 } 861 862 musics = [null, null, null, null, null]; 863 music_len = [0.0f, 0.0f, 0.0f, 0.0f, 0.0f]; 864 music_name = ["", "", "", "", ""]; 865 866 musics[0] = Mix_LoadMUS("music/GraveBeholders_TheSadnessOfMyWorld.ogg"); 867 if(!musics[0]) { 868 writefln("Mix_LoadMUS 'music/GraveBeholders_TheSadnessOfMyWorld.ogg': %s", Mix_GetError().to!(string)()); 869 } 870 music_len[0] = 632.0; 871 music_name[0] = "Grave Beholders: The Sadness Of My World"; 872 873 musics[1] = Mix_LoadMUS("music/SergeySirotin_Magic.ogg"); 874 if(!musics[1]) { 875 writefln("Mix_LoadMUS 'music/SergeySirotin_Magic.ogg': %s", Mix_GetError().to!(string)()); 876 } 877 music_len[1] = 232.6; 878 music_name[1] = "Sergey Sirotin: Magic"; 879 880 musics[2] = Mix_LoadMUS("music/OlegGurtovoy_FreeFlight.ogg"); 881 if(!musics[2]) { 882 writefln("Mix_LoadMUS 'music/OlegGurtovoy_FreeFlight.ogg': %s", Mix_GetError().to!(string)()); 883 } 884 music_len[2] = 234.2; 885 music_name[2] = "Oleg Gurtovoy: Free Flight"; 886 887 musics[3] = Mix_LoadMUS("music/PaulWhite_ViolinQuartet.ogg"); 888 if(!musics[3]) { 889 writefln("Mix_LoadMUS 'music/PaulWhite_ViolinQuartet.ogg': %s", Mix_GetError().to!(string)()); 890 } 891 music_len[3] = 206.5; 892 music_name[3] = "Paul White: Violin Quartet"; 893 894 musics[4] = Mix_LoadMUS("music/SergeySirotin_NightCity.ogg"); 895 if(!musics[4]) { 896 writefln("Mix_LoadMUS 'music/SergeySirotin_NightCity.ogg': %s", Mix_GetError().to!(string)()); 897 } 898 music_len[4] = 249.8; 899 music_name[4] = "Sergey Sirotin: Night City"; 900 901 music_start_tick = cast(long)SDL_GetTicks(); 902 903 music = true; 904 905 super(this); 906 907 gs.syncTime(); 908 } 909 910 ~this() 911 { 912 /*foreach (model; models) 913 { 914 aiReleaseImport(model); 915 } 916 aiDetachAllLogStreams();*/ 917 } 918 919 void loadingMessage(GlobalState gs) 920 { 921 glClearColor(0.0, 0.0, 0.0, 1.0); 922 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 923 glDisable(GL_LIGHTING); 924 925 glMatrixMode(GL_MODELVIEW); 926 glLoadIdentity(); 927 928 float tmp = aspectRatio/15.0; 929 glScalef(tmp, tmp, tmp); 930 931 glRotatef(15.0+params[7]*10,-1,1,0); 932 glRotatef(1.0443,0,0,1); 933 glScalef(0.75, 0.75, 0.75); 934 glTranslatef(2.2, 2.0, 0.0); 935 936 glPushMatrix(); 937 glTranslatef(-5.0, 1.0, 0.0); 938 939 glBindTexture(GL_TEXTURE_2D, textures["font"]); 940 glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR); 941 glEnable(GL_COLOR_MATERIAL); 942 glColor4f(1.0, 1.0, 0.0, 1.0); 943 print_text("Loading...\n"~ 944 "Please wait"); 945 glPopMatrix(); 946 947 glScalef(0.5, 0.5, 0.5); 948 glTranslatef(-34.0, -14.0, 0.0); 949 glColor4f(0.75, 0.75, 0.75, 1.0); 950 print_text(" \"Dizzy\", \"The Yolkfolk\" and all related characters and titles\n"~ 951 "are trademarks of Oliver Twins Limited and The Codemasters Software\n"~ 952 " Company Limited."); 953 glEnable(GL_LIGHTING); 954 955 SDL_RenderPresent(gs.renderer); 956 } 957 958 double aspectRatio; 959 960 void initViewPort(int w, int h) 961 { 962 aspectRatio = cast(double) w / h; 963 964 glMatrixMode(GL_PROJECTION); 965 glLoadIdentity(); 966 967 GLfloat windowWidth; GLfloat windowHeight; 968 if (w <= h) 969 { 970 windowWidth = 1; 971 windowHeight = 1/aspectRatio; 972 glOrtho(-windowWidth, windowWidth, -windowHeight, windowHeight, 100.0, -100.0); 973 } 974 else 975 { 976 windowWidth = 1*aspectRatio; 977 windowHeight = 1; 978 glOrtho(-windowWidth, windowWidth, -windowHeight, windowHeight, 100.0, -100.0); 979 } 980 981 glViewport(0, 0, w, h); 982 983 //Initialize Modelview Matrix 984 glMatrixMode( GL_MODELVIEW ); 985 glLoadIdentity(); 986 } 987 988 void toGame(GlobalState gs) 989 { 990 if (sl_tid == Tid.init) 991 { 992 sl_tid = spawn(&scene_loader, &screens, 993 &screen_names, 994 cast(int) round(scrx/30.0), 995 cast(int) round(scry/17.0), 996 5, thisTid); 997 } 998 999 SDL_SetRenderTarget(gs.renderer, null); 1000 initViewPort(gs.screen.w+32*6, gs.screen.h); 1001 glEnable(GL_DEPTH_TEST); 1002 glEnable(GL_CULL_FACE); 1003 glEnable(GL_TEXTURE_2D); 1004 glUseProgram(0); 1005 1006 if (music) 1007 { 1008 if (Mix_PlayMusic(musics[track], -1) == -1) 1009 { 1010 writefln("Mix_PlayMusic: %s", 1011 Mix_GetError().to!(string)()); 1012 } 1013 1014 if(Mix_SetMusicPosition(( 1015 (SDL_GetTicks() - music_start_tick)/1000.0)% 1016 music_len[track]) == -1) { 1017 writefln("Mix_SetMusicPosition: %s\n", 1018 Mix_GetError().to!(string)()); 1019 } 1020 1021 print_message(TEMP_MESSAGES.PLAYS, " "~music_name[track]); 1022 } 1023 } 1024 1025 void fromGame(GlobalState gs) 1026 { 1027 if (sl_tid != Tid.init) 1028 { 1029 sl_tid.send(true); 1030 sl_tid = Tid.init; 1031 } 1032 1033 glDisable(GL_DEPTH_TEST); 1034 glDisable(GL_CULL_FACE); 1035 glMatrixMode(GL_MODELVIEW); 1036 glLoadIdentity(); 1037 1038 Mix_HaltMusic(); 1039 Mix_HaltChannel(-1); 1040 } 1041 1042 float[8] params = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]; 1043 bool p_changed; 1044 1045 void parametrizer() 1046 { 1047 int i; 1048 if (keys & CTRL_KEY) 1049 i += 1; 1050 if (keys & SHIFT_KEY) 1051 i += 2; 1052 1053 if (keys & LEFT_KEY) 1054 params[i*2+0] -= 0.01; 1055 if (keys & RIGHT_KEY) 1056 params[i*2+0] += 0.01; 1057 1058 if (keys & DOWN_KEY) 1059 params[i*2+1] -= 0.01; 1060 if (keys & UP_KEY) 1061 params[i*2+1] += 0.01; 1062 1063 if (keys & (LEFT_KEY|RIGHT_KEY|DOWN_KEY|UP_KEY)) 1064 { 1065 p_changed = true; 1066 } 1067 else 1068 { 1069 if (p_changed) writefln("params = %s", params); 1070 p_changed = false; 1071 } 1072 } 1073 1074 int draw_tree; 1075 1076 bool all_items_in_the_castle() 1077 { 1078 Item[] items = [kitchen_knife, player, baloon, umbrella, stone1, stone2, bucket, blanket, spade, whistle]; 1079 foreach (item; items) 1080 { 1081 if (!item.in_the_castle) return false; 1082 } 1083 return true; 1084 } 1085 1086 override void draw(GlobalState gs) 1087 { 1088 float tmp; 1089 1090 if (reinit_draw > 0) 1091 { 1092 toGame(gs); 1093 reinit_draw--; 1094 } 1095 1096 glClearColor(0.0, 0.0, 0.0, 1.0); 1097 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1098 1099 glMatrixMode(GL_MODELVIEW); 1100 glLoadIdentity(); 1101 1102 glRotatef(15.0+params[7]*10,-1,1,0); 1103 glRotatef(1.0443,0,0,1); 1104 1105 tmp = aspectRatio/15.0; 1106 glScalef(tmp, tmp, tmp); 1107 1108 bool star_found; 1109 foreach(star; stars) 1110 { 1111 star_found = star.set_light(gs); 1112 if (star_found) break; 1113 } 1114 1115 if (!star_found) 1116 glDisable(GL_LIGHT1); 1117 1118 // Light Tree 1119 if (scrx == 0.0 && scry == 0.0) 1120 { 1121 glEnable(GL_LIGHT2); 1122 glLightfv(GL_LIGHT2, GL_POSITION, [11.8f, -5.8f, 1.0f, 1.0f].ptr); 1123 glLightfv(GL_LIGHT2, GL_DIFFUSE, 1124 [0.0f, 1125 cast(float)(0.065f + 0.03*sin(cast(float)frame/50)), 1126 cast(float)(0.065f + 0.03*cos(cast(float)frame/50)), 1127 1.0f].ptr); 1128 glLighti(GL_LIGHT2, GL_QUADRATIC_ATTENUATION, 1); 1129 } 1130 else 1131 { 1132 glDisable(GL_LIGHT2); 1133 } 1134 1135 SC sc = SC(cast(int)round(scrx/30), cast(int)round(scry/17)); 1136 1137 /* Underground */ 1138 if (sc.y < 0 && sc.x >= 8 && sc.x <= 14 && 1139 !(sc.x == 14 && sc.y == -1) || sc.x == 15 && sc.y == -4) 1140 { 1141 if (sc.y == -1) 1142 { 1143 glEnable(GL_LIGHT0); 1144 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, [0.0f, 0.0f, 0.0f, 1.0f].ptr); 1145 1146 glLightfv(GL_LIGHT0, GL_POSITION, [0f, 15f, 5.0f, 1.0f].ptr); 1147 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, [0.0f, 0.5f, -0.1f].ptr); 1148 glLighti(GL_LIGHT0, GL_SPOT_EXPONENT, 90); 1149 glLighti(GL_LIGHT0, GL_SPOT_CUTOFF, 180); 1150 glLighti(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0); 1151 glLighti(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 3); 1152 } 1153 else 1154 { 1155 glDisable(GL_LIGHT0); 1156 } 1157 } 1158 else 1159 { 1160 glEnable(GL_LIGHT0); 1161 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, [0.2f, 0.2f, 0.2f, 1.0f].ptr); 1162 glLightfv(GL_LIGHT0, GL_POSITION, [-75f, -75f, 150.0f, 1.0f].ptr); 1163 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, [0.5f, 0.5f, -1.0f].ptr); 1164 glLighti(GL_LIGHT0, GL_SPOT_EXPONENT, 64); 1165 glLighti(GL_LIGHT0, GL_SPOT_CUTOFF, 90); 1166 glLighti(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1); 1167 glLighti(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0); 1168 } 1169 1170 //Sky 1171 glEnable(GL_COLOR_MATERIAL); 1172 glDisable(GL_LIGHTING); 1173 glBindTexture(GL_TEXTURE_2D, 0); 1174 glPushMatrix(); 1175 glTranslatef(-2.0, -2.0, 0.0); 1176 glBegin(GL_POLYGON); 1177 glColor4f(0.965, 0.665, 0.644, 1.0); 1178 glVertex3f(16.0, 16.0/aspectRatio, 10.0); 1179 glVertex3f(-16.0, 16.0/aspectRatio, 10.0); 1180 glColor4f(1.000, 0.807, 0.617, 1.0); 1181 glVertex3f(-16.0, -16.0/aspectRatio, 10.0); 1182 glVertex3f(16.0, -16.0/aspectRatio, 10.0); 1183 glEnd(); 1184 glPopMatrix(); 1185 glColor4f(1.0, 1.0, 1.0, 1.0); 1186 glDisable(GL_COLOR_MATERIAL); 1187 1188 glPushMatrix(); 1189 glTranslatef(-scrx, -scry, 0.0); 1190 1191 /* Underground */ 1192 if (sc.y < 0 && sc.x >= 8 && sc.x <= 14 && 1193 !(sc.x == 14 && sc.y == -1) || sc.x == 15 && sc.y == -4) 1194 { 1195 glEnable(GL_LIGHT2); 1196 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, [0.0f, 0.0f, 0.0f, 1.0f].ptr); 1197 glLightfv(GL_LIGHT2, GL_DIFFUSE, 1198 [0.3f, 1199 cast(float)(0.365f + 0.15*sin(cast(float)frame/50)), 1200 cast(float)(0.365f + 0.15*cos(cast(float)frame/50)), 1201 1.0f].ptr); 1202 glLightf(GL_LIGHT2, GL_QUADRATIC_ATTENUATION, 0.25f); 1203 1204 if (light_branch.inventory) 1205 { 1206 glLightfv(GL_LIGHT2, GL_POSITION, [the_hero.x, the_hero.y+1.5f, the_hero.z+8.0f, 1.0f].ptr); 1207 } 1208 else 1209 { 1210 glLightfv(GL_LIGHT2, GL_POSITION, [light_branch.x, light_branch.y+.5f, light_branch.z+8.0f, 1.0f].ptr); 1211 } 1212 } 1213 1214 the_hero.draw(gs); 1215 1216 foreach(star; stars) 1217 { 1218 star.draw(gs); 1219 } 1220 1221 stars[0].force_draw(gs); 1222 1223 /*if (the_hero.show_sensors) 1224 recursive_render(gs, models["solid"]); 1225 else*/ 1226 { 1227 if (sc !in screen_lists) 1228 { 1229 if (sc !in screens) 1230 { 1231 loadingMessage(gs); 1232 return; 1233 } 1234 1235 screen_lists[sc] = glGenLists(1); 1236 if (screen_lists[sc] <= 0) 1237 throw new Exception(format("Error while glGenLists: %s", screen_lists[sc])); 1238 glNewList(screen_lists[sc], GL_COMPILE_AND_EXECUTE); 1239 recursive_render(gs, screens[sc], null, null, true, sc.y >= 0); 1240 glEndList(); 1241 1242 screens[sc] = null; 1243 1244 foreach(scc; screen_lists.keys()) 1245 { 1246 if (scc !in screens) 1247 { 1248 glDeleteLists(screen_lists[scc], 1); 1249 screen_lists.remove(scc); 1250 } 1251 } 1252 1253 //writefln("%s", GC.stats()); 1254 } 1255 else 1256 { 1257 glCallList(screen_lists[sc]); 1258 } 1259 } 1260 1261 foreach(tree; trees) 1262 { 1263 tree.draw(gs); 1264 } 1265 1266 foreach (ref item; items) 1267 { 1268 item.draw(gs); 1269 } 1270 1271 foreach(anim; animations) 1272 { 1273 anim.draw(gs); 1274 } 1275 1276 bag_bug_anim.draw(gs); 1277 1278 if (dizzy_used_knife_quest_state <= 0) 1279 { 1280 glPushMatrix(); 1281 glTranslatef(331.78, -3.85, 4.0); 1282 recursive_render(gs, models["branch-of-tree-full"]); 1283 glPopMatrix(); 1284 } 1285 else 1286 { 1287 glPushMatrix(); 1288 glTranslatef(331.78, -3.85, 4.0); 1289 recursive_render(gs, models["branch-of-tree-cut"]); 1290 glPopMatrix(); 1291 1292 float f = the_hero.frame; 1293 1294 if (dizzy_used_knife_quest_state == 1 && f < 100.0) 1295 { 1296 glPushMatrix(); 1297 glTranslatef(326.40, 2.01 - 8.0*f/100.0, -0.50); 1298 glRotatef(f*8.0, 0.0, 0.0, 1.0); 1299 recursive_render(gs, models["branch-on-tree"]); 1300 glPopMatrix(); 1301 } 1302 else if (dizzy_used_knife_quest_state <= 2) 1303 { 1304 glPushMatrix(); 1305 glTranslatef(326.40, -6.0, -0.50); 1306 glRotatef(800.0, 0.0, 0.0, 1.0); 1307 recursive_render(gs, models["branch-on-tree"]); 1308 glPopMatrix(); 1309 } 1310 } 1311 1312 if (dizzy_throw_branch_quest_state == 1 || dizzy_throw_branch_quest_state == 2) 1313 { 1314 glPushMatrix(); 1315 1316 auto b = &branch_quest_variables; 1317 1318 glTranslatef(b.x, b.y, 0.0); 1319 1320 glTranslatef(1.5, 2.5, 0.0); 1321 glRotatef(b.degree,0,0,1); 1322 glTranslatef(-1.5, -2.5, 0.0); 1323 1324 glRotatef(-90,0,1,0); 1325 1326 glTranslatef(0.0, 1.9, 0.0); 1327 glRotatef(90.0, 1.0, 0.0, 0.0); 1328 glTranslatef(0.0, -1.9, 0.0); 1329 glTranslatef(-0.9, 0.5, -0.1); 1330 1331 glRotatef(55.0, 0.0, 1.0, 0.0); 1332 glRotatef(-60.0, 0.0, 0.0, 1.0); 1333 glScalef(0.5, 0.5, 0.5); 1334 1335 recursive_render(gs, models["branch"]); 1336 1337 glPopMatrix(); 1338 } 1339 else if (dizzy_throw_branch_quest_state == 3 || dizzy_throw_branch_quest_state == 4) 1340 { 1341 glPushMatrix(); 1342 1343 auto b = &branch_quest_variables; 1344 1345 float f = (dog.frame*4)%240; 1346 float translate = 0.0; 1347 1348 if (f < 120.0) 1349 translate = 0.2 - 0.4*f/120.0; 1350 else if (f < 240.0) 1351 translate = -0.2 + 0.4*(f - 120.0)/120.0; 1352 1353 glTranslatef(dog.x, dog.y + b.y + translate, dog.z); 1354 1355 glTranslatef(-3.0, -0.2, 0.3); 1356 glRotatef(-61.5, 0.430, -0.875, 0.224); 1357 glScalef(0.5, 0.5, 0.5); 1358 1359 recursive_render(gs, models["branch"]); 1360 1361 glPopMatrix(); 1362 } 1363 1364 if (scrx == 0.0 && scry == 0.0) 1365 { 1366 glPushMatrix(); 1367 glTranslatef(-11.8, -6.4, 3.2); 1368 recursive_render(gs, models["rocket"]); 1369 glPopMatrix(); 1370 } 1371 1372 switch(rope_state) 1373 { 1374 case 0: 1375 break; 1376 case 1: 1377 rope1.draw(gs); 1378 break; 1379 case 2: 1380 rope2.draw(gs); 1381 break; 1382 case 3: 1383 rope3.draw(gs); 1384 break; 1385 default: 1386 assert(0); 1387 } 1388 1389 glPopMatrix(); 1390 1391 //Indicators 1392 glDisable(GL_LIGHTING); 1393 1394 glScalef(0.75, 0.75, 0.75); 1395 1396 glPushMatrix(); 1397 glTranslatef(2.2, 2.0, 0.0); 1398 1399 if ((the_hero.y - scry) > 4.0) 1400 indicators_down = true; 1401 1402 if ((the_hero.y - scry) < -4.0) 1403 indicators_down = false; 1404 1405 float iy = 21.0/aspectRatio-2.0; 1406 if (indicators_down) 1407 iy = -21.0/aspectRatio+1.0; 1408 1409 glBindTexture(GL_TEXTURE_2D, textures["live"]); 1410 1411 glBegin(GL_POLYGON); 1412 glTexCoord2f(0.0, 0.0); 1413 glVertex3f(-20.0, iy+1.0, -10.0); 1414 glTexCoord2f(0.0, 1.0); 1415 glVertex3f(-20.0, iy, -10.0); 1416 glTexCoord2f(the_hero.lives >=0 ? the_hero.lives : 1, 1.0); 1417 glVertex3f(-20.0 + (the_hero.lives >=0 ? the_hero.lives : 1), iy, -10.0); 1418 glTexCoord2f(the_hero.lives >=0 ? the_hero.lives : 1, 0.0); 1419 glVertex3f(-20.0 + (the_hero.lives >=0 ? the_hero.lives : 1), iy+1.0, -10.0); 1420 glEnd(); 1421 1422 glBindTexture(GL_TEXTURE_2D, textures["energy"]); 1423 glBegin(GL_POLYGON); 1424 glTexCoord2f(0.0, 0.0); 1425 glVertex3f(-16.0, iy+1.0, -10.0); 1426 glTexCoord2f(0.0, 1.0); 1427 glVertex3f(-16.0, iy, -10.0); 1428 glTexCoord2f(energy/100.0, 1.0); 1429 glVertex3f(-16.0 + 8.0*energy/100.0, iy, -10.0); 1430 glTexCoord2f(energy/100.0, 0.0); 1431 glVertex3f(-16.0 + 8.0*energy/100.0, iy+1.0, -10.0); 1432 glEnd(); 1433 1434 int scrX = cast(int) round(scrx/30); 1435 int scrY = cast(int) round(scry/17); 1436 1437 glPushMatrix(); 1438 glBindTexture(GL_TEXTURE_2D, textures["font"]); 1439 glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR); 1440 glEnable(GL_COLOR_MATERIAL); 1441 if (the_hero.lives < 0) 1442 { 1443 glPushMatrix(); 1444 glTranslatef(-19.0, iy+1.0, 0.0); 1445 glColor4f(1.0, 1.0, 0.0, 1.0); 1446 print_text(format("%2d", the_hero.lives)); 1447 glPopMatrix(); 1448 } 1449 glTranslatef(-7.0, iy+1.0, 0.0); 1450 glColor4f(1.0, 1.0, 0.0, 1.0); 1451 print_text(format("%02d", num_stars)); 1452 glTranslatef(3.0, 0.0, 0.0); 1453 glColor4f(1.0, 1.0, 1.0, 1.0); 1454 string screen_name; 1455 if ((SC(scrX, scrY) in screen_names)) 1456 { 1457 final switch(lang) 1458 { 1459 case LANG.EN: 1460 screen_name = screen_names[SC(scrX, scrY)]; 1461 break; 1462 1463 case LANG.RU: 1464 screen_name = screen_names_ru[SC(scrX, scrY)]; 1465 break; 1466 } 1467 } 1468 print_text(screen_name); 1469 1470 /*glTranslatef(-8.0, -2.0, 0.0); 1471 print_text(format("FPS %.02f", 1472 gs.fps_frames*1000.0/gs.fps_time));*/ 1473 1474 glPopMatrix(); 1475 1476 draw_temp_message(); 1477 1478 glDisable(GL_COLOR_MATERIAL); 1479 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1480 1481 dialogs.draw(gs); 1482 glPopMatrix(); 1483 } 1484 1485 void draw_temp_message() 1486 { 1487 if (frame < temp_message_frame_from || 1488 frame > temp_message_frame_to) return; 1489 1490 float f = frame - temp_message_frame_from; 1491 glPushMatrix(); 1492 1493 string msg; 1494 final switch (lang) 1495 { 1496 case LANG.EN: 1497 msg = temp_messages[temp_message] ~ temp_message_str; 1498 break; 1499 case LANG.RU: 1500 msg = temp_messages_ru[temp_message] ~ temp_message_str; 1501 break; 1502 } 1503 1504 if (temp_message == TEMP_MESSAGES.PLAYS) 1505 { 1506 glScalef(0.5, 0.5, 0.5); 1507 glTranslatef(0.0, -10.0, 0.0); 1508 } 1509 1510 float alpha = 1.0; 1511 if (f < 50) alpha = f/50.0; 1512 if (temp_message_frame_to - 50 > frame) 1513 alpha = (temp_message_frame_to-frame)/50.0; 1514 1515 glColor4f(1.0, 1.0, 0.0, alpha); 1516 1517 immutable (char)* second_line = msg.find("\n").ptr; 1518 if (second_line == null) second_line = msg.ptr + msg.length; 1519 1520 glTranslatef(-0.5*msg[0..second_line - msg.ptr].walkLength(), -6.0, 0.0); 1521 1522 print_text(msg); 1523 1524 glPopMatrix(); 1525 } 1526 1527 bool paused; 1528 int slow = -1; 1529 int num_stars = 0; 1530 float energy = 100.0; 1531 bool indicators_down; 1532 int inv_num = -1; 1533 STATE state = STATE.NO_DIALOGS; 1534 1535 override bool tick(GlobalState gs) 1536 { 1537 SC sc = SC(cast(int)round(scrx/30), cast(int)round(scry/17)); 1538 if (sc in screen_names && sc !in screen_lists && sc !in screens) 1539 return true; 1540 1541 if (slow >= 0) 1542 { 1543 slow++; 1544 if (slow >= 10) slow = 0; 1545 else return true; 1546 } 1547 1548 dialogs.tick(gs); 1549 1550 if (the_hero.energy-0.5 > energy) 1551 { 1552 if (music_state != MUSIC_STATE.ENERGY_PLUS) 1553 { 1554 music_state = MUSIC_STATE.ENERGY_PLUS; 1555 1556 if (the_hero.sounds && energy_plus) 1557 { 1558 if (Mix_PlayMusic(energy_plus, 1) == -1) 1559 { 1560 writefln("Mix_PlayMusic: %s", 1561 Mix_GetError().to!(string)()); 1562 } 1563 1564 energy_start_tick = SDL_GetTicks() - cast(long)(1000*energy/100.0); 1565 1566 if(Mix_SetMusicPosition(energy/100.0) == -1) { 1567 writefln("Mix_SetMusicPosition: %s\n", 1568 Mix_GetError().to!(string)()); 1569 } 1570 } 1571 } 1572 1573 energy += 1.0; 1574 } 1575 else if (the_hero.energy+0.5 < energy) 1576 { 1577 if (music_state != MUSIC_STATE.ENERGY_MINUS) 1578 { 1579 music_state = MUSIC_STATE.ENERGY_MINUS; 1580 1581 if (the_hero.sounds && energy_minus) 1582 { 1583 if (Mix_PlayMusic(energy_minus, 1) == -1) 1584 { 1585 writefln("Mix_PlayMusic: %s", 1586 Mix_GetError().to!(string)()); 1587 } 1588 1589 energy_start_tick = SDL_GetTicks() - cast(long)(1000*(100.0-energy)/100.0); 1590 1591 if(Mix_SetMusicPosition((100.0-energy)/100.0) == -1) { 1592 writefln("Mix_SetMusicPosition: %s\n", 1593 Mix_GetError().to!(string)()); 1594 } 1595 } 1596 } 1597 1598 energy -= 1.0; 1599 } 1600 else 1601 { 1602 if (music_state != MUSIC_STATE.MUSIC && 1603 (energy != 100.0 && energy != 0.0 || 1604 (SDL_GetTicks() - energy_start_tick) > 2000)) 1605 { 1606 music_state = MUSIC_STATE.MUSIC; 1607 1608 if (the_hero.sounds) 1609 { 1610 if (music) 1611 { 1612 if (Mix_PlayMusic(musics[track], -1) == -1) 1613 { 1614 writefln("Mix_PlayMusic: %s", 1615 Mix_GetError().to!(string)()); 1616 } 1617 1618 if(Mix_SetMusicPosition(( 1619 (SDL_GetTicks() - music_start_tick)/1000.0)% 1620 music_len[track]) == -1) { 1621 writefln("Mix_SetMusicPosition: %s\n", 1622 Mix_GetError().to!(string)()); 1623 } 1624 } 1625 else 1626 { 1627 Mix_HaltMusic(); 1628 } 1629 } 1630 } 1631 } 1632 1633 auto b = &branch_quest_variables; 1634 1635 if (dizzy_throw_branch_quest_state == 1) 1636 { 1637 if (!b.st) 1638 { 1639 b.st = 1; 1640 b.x = the_hero.x; 1641 b.y = the_hero.y; 1642 b.dx = (366.7 - b.x)/136; 1643 b.dy = 0.23; 1644 b.degree = 0.0; 1645 } 1646 1647 if (b.y < -1.5 && b.dy < 0.0) 1648 { 1649 dizzy_throw_branch_quest_state++; 1650 } 1651 1652 b.x += b.dx; 1653 b.y += b.dy; 1654 b.degree += 2.0; 1655 1656 if (b.dy > -0.1) 1657 b.dy -= the_hero.MARS_G; 1658 } 1659 else if (dizzy_throw_branch_quest_state == 2) 1660 { 1661 if (dog.state == dog.STATE.GO_LEFT) 1662 { 1663 dizzy_throw_branch_quest_state++; 1664 b.st = 0; 1665 b.x = 0.0; 1666 b.y = 0.0; 1667 b.dy = 0.0; 1668 } 1669 1670 if (b.dy > -0.1) 1671 b.dy -= the_hero.MARS_G; 1672 } 1673 else if (dizzy_throw_branch_quest_state == 3 && 1674 (dog.state == dog.STATE.WATCH || dog.state == dog.STATE.FLY_AWAY)) 1675 { 1676 dizzy_throw_branch_quest_state++; 1677 } 1678 else if (dizzy_throw_branch_quest_state == 4) 1679 { 1680 b.y += b.dy; 1681 if (b.dy > -0.1) 1682 b.dy -= the_hero.MARS_G; 1683 1684 if (b.y < -2.0) 1685 { 1686 if (dizzy_cuts_rope_quest_state < 0) 1687 dizzy_throw_branch_quest_state = -1; 1688 else 1689 dizzy_throw_branch_quest_state++; 1690 1691 branch.x = 358.8; 1692 branch.y = -5.0; 1693 branch.used = false; 1694 } 1695 } 1696 1697 if (state == STATE.DIZZY_USED_KNIFE_ANIM) 1698 { 1699 if (dizzy_used_knife_quest_state == 0 && !the_hero.tick(gs)) 1700 { 1701 dizzy_used_knife_quest_state++; 1702 collision_objects["solid"].remove("BranchForBreak"); 1703 reset_collision_cache(); 1704 the_hero.reset_anim(); 1705 the_hero.start_fall(); 1706 } 1707 else if (dizzy_used_knife_quest_state == 1) 1708 { 1709 the_hero.tick(gs); 1710 if (the_hero.frame >= 400) 1711 { 1712 dizzy_used_knife_quest_state++; 1713 state = STATE.NO_DIALOGS; 1714 the_hero.reset_anim(); 1715 } 1716 } 1717 } 1718 else if (state == STATE.DIZZY_THROW_BRANCH_ANIM) 1719 { 1720 dog.tick(gs); 1721 if (dizzy_throw_branch_quest_state <= 1 && !the_hero.tick(gs)) 1722 { 1723 the_hero.reset_anim(); 1724 state = STATE.NO_DIALOGS; 1725 } 1726 if (the_hero.frame == 45) 1727 dizzy_throw_branch_quest_state = 1; 1728 } 1729 if (state == STATE.DIZZY_CUTS_ROPE_ANIM) 1730 { 1731 dog.tick(gs); 1732 if (!the_hero.tick(gs)) 1733 { 1734 dog.cut_rope(); 1735 the_hero.reset_anim(); 1736 state = STATE.NO_DIALOGS; 1737 } 1738 } 1739 if (state == STATE.DIZZY_DIG_ANIM) 1740 { 1741 frame++; 1742 ground_garden.tick(gs); 1743 1744 if (frame - ground_garden.frame == 100) 1745 { 1746 stone2.x = the_hero.x - 1.0; 1747 stone2.y = the_hero.y; 1748 } 1749 1750 if (!the_hero.tick(gs)) 1751 { 1752 the_hero.x = 326.5; 1753 the_hero.reset_anim(); 1754 state = STATE.NO_DIALOGS; 1755 } 1756 } 1757 if (state == STATE.THINGS_SWEEP_AWAY_ZAKS_ANIM) 1758 { 1759 if (!paused) 1760 { 1761 frame++; 1762 things_sweep_away_zaks.tick(gs); 1763 water3.tick(gs); 1764 1765 if (things_sweep_away_zaks.frame > 600) 1766 { 1767 stones.frame = frame; 1768 stones.tick(gs); 1769 stone3.x = 413.4; 1770 stone3.y = -84.3; 1771 state++; 1772 } 1773 } 1774 } 1775 else if (state != STATE.NO_DIALOGS) 1776 { 1777 if (the_hero.energy <= 0.0) 1778 the_hero.tick(gs); 1779 } 1780 else if (!paused) 1781 { 1782 //degrees += 1.0; 1783 frame++; 1784 if (things_sweep_away_zaks.frame > 1700) things_sweep_away_zaks.hide(); 1785 1786 the_hero.tick(gs); 1787 1788 if (the_hero.energy <= 0.0) 1789 { 1790 if (the_hero.killed_by.startsWith("Stalactite")) 1791 { 1792 state = STATE.PIERCED_BY_STALACTITE; 1793 } 1794 else if (the_hero.killed_by.startsWith("Stalagmite")) 1795 { 1796 state = STATE.PIERCED_BY_STALAGMITE; 1797 } 1798 else if (the_hero.killed_by == "Meteorite") 1799 { 1800 state = STATE.HIT_BY_METEORITE; 1801 } 1802 else if (the_hero.killed_by.startsWith("Acid")) 1803 { 1804 state = STATE.DISSOLVED_IN_ACID; 1805 } 1806 else if (the_hero.killed_by.startsWith("Lava")) 1807 { 1808 state = STATE.BURNED_IN_LAVA; 1809 } 1810 else if (the_hero.killed_by.startsWith("Pin")) 1811 { 1812 state = STATE.DAMAGED_BY_PIN; 1813 } 1814 else if (the_hero.killed_by.startsWith("Rock")) 1815 { 1816 state = STATE.HIT_BY_ROCK; 1817 } 1818 else if (the_hero.killed_by.startsWith("Flame")) 1819 { 1820 state = STATE.BURNED_IN_FLAME; 1821 } 1822 else if (the_hero.killed_by.startsWith("Pressure")) 1823 { 1824 state = STATE.CRUSHED_BY_PRESSURE; 1825 } 1826 else 1827 { 1828 assert(0, format("Unknown danger object: %s", the_hero.killed_by)); 1829 } 1830 } 1831 1832 if (the_hero.x > martian_engineer.x - 1.5 && 1833 the_hero.y > martian_engineer.y - 0.5 && 1834 martian_engineer.z == 0.0) 1835 { 1836 state = STATE.MARTIAN_ENGINEER_GET_AWAY; 1837 } 1838 1839 if (zaks.y == zaks.def_y && 1840 the_hero.x > zaks.x - 2.0 && 1841 the_hero.y > zaks.y - 0.5 && 1842 the_hero.y < zaks.y + 10.5) 1843 { 1844 the_hero.x = zaks.x - 2.0; 1845 } 1846 1847 // Location: Water near Zaks 1848 if ( 478.5 < the_hero.x && the_hero.x < 483.6 && 1849 the_hero.y < -162.0 ) 1850 { 1851 the_hero.y = -162.0; 1852 } 1853 1854 // Location: In the bam 1855 if ( 293.7 < the_hero.x && the_hero.x < 304.1 && 1856 26.3 < the_hero.y && the_hero.y < 29.2 ) 1857 { 1858 the_hero.z = (the_hero.y-26.3); 1859 } 1860 else if ( the_hero.x >= 280.0 && the_hero.x < 320.0 && 26.2 < the_hero.y && the_hero.y < 29.2 ) 1861 { 1862 the_hero.z = 0.0; 1863 } 1864 1865 // Location: Two passes and umbrella 1866 if ( the_hero.z < 0.0 && abs(the_hero.x - 511.5) < 4.0 && 1867 abs(the_hero.y+4.6) < 2.2 ) 1868 { 1869 the_hero.z = -2.6; 1870 } 1871 else if (the_hero.z < 0.0 && abs(the_hero.x - 511.5) >= 4.0 && 1872 abs(the_hero.x-511.5) < 7.0 && 1873 abs(the_hero.y+4.6) < 2.2) 1874 { 1875 the_hero.z = -2.6 + 2.6*(abs(the_hero.x-511.5)-4.0)/3.0; 1876 } 1877 else if (the_hero.z < 0.0 && abs(the_hero.x - 511.5) >= 7.0 && 1878 abs(the_hero.x-511.5) < 8.0 && 1879 abs(the_hero.y+4.6) < 2.2) 1880 { 1881 the_hero.z = 0.0; 1882 } 1883 1884 if (abs(the_hero.x-511.5) < 2.6 && 1885 -0.6 < the_hero.y && the_hero.y < 4.3) 1886 { 1887 the_hero.z = -2.6*(4.3 - the_hero.y)/4.9; 1888 } 1889 else if (abs(the_hero.x-511.5) < 3.6 && 1890 -0.6 < the_hero.y && the_hero.y < 5.3) 1891 { 1892 the_hero.z = 0.0; 1893 } 1894 1895 foreach (animation; animations) 1896 { 1897 animation.tick(gs); 1898 } 1899 1900 bag_bug_anim.tick(gs); 1901 1902 switch(rope_state) 1903 { 1904 case 0: 1905 the_hero.rope = null; 1906 break; 1907 case 1: 1908 the_hero.rope = rope1; 1909 rope1.tick(gs); 1910 break; 1911 case 2: 1912 the_hero.rope = rope2; 1913 rope2.tick(gs); 1914 break; 1915 case 3: 1916 the_hero.rope = rope3; 1917 rope3.tick(gs); 1918 break; 1919 default: 1920 assert(0); 1921 } 1922 1923 if ((bucket_of_water.inventory || 1924 bucket_covered.inventory) && 1925 the_hero.fall && bucket_anim.frame < 0) 1926 { 1927 foreach(i, ref item_num; inventory) 1928 { 1929 if (items[item_num] == bucket_of_water) 1930 { 1931 bucket_of_water.inventory = false; 1932 bucket_of_water.used = true; 1933 inventory = inventory[0..i]~inventory[i+1..$]; 1934 break; 1935 } 1936 } 1937 foreach(i, ref item_num; inventory) 1938 { 1939 if (items[item_num] == bucket_covered) 1940 { 1941 bucket_covered.inventory = false; 1942 bucket_covered.used = true; 1943 item_num += 3; 1944 break; 1945 } 1946 } 1947 bucket_anim.start_anim([the_hero.x, the_hero.y, the_hero.z]); 1948 } 1949 1950 if (bucket_anim.frame >= 0 && 1951 frame - bucket_anim.frame >= 200) 1952 { 1953 bucket_anim.frame = -1; 1954 bucket.used = false; 1955 bucket.inventory = false; 1956 bucket.x = the_hero.x - 2.0; 1957 bucket.y = the_hero.y; 1958 bucket.z = the_hero.z; 1959 } 1960 1961 if (abs(scrx - 330.0f) < 1.0f && abs(scry + 17.0f) < 1.0f && track == 0) 1962 { 1963 track = 1; 1964 music_start_tick = cast(long)SDL_GetTicks(); 1965 play_music(); 1966 } 1967 1968 // Location: Dangerous deep 1969 if (abs(scrx - 240.0f) < 1.0f && abs(scry + 85.0f) < 1.0f) 1970 { 1971 if (!pressprot.inventory) 1972 { 1973 the_hero.energy = min(the_hero.energy, (the_hero.y + 93.0f)/16.0f*100.0f); 1974 if (the_hero.energy <= 0.0) 1975 { 1976 the_hero.die("Pressure"); 1977 } 1978 } 1979 } 1980 1981 // Location: And can not see the bottom 1982 if (abs(scrx - 240.0f) < 1.0f && abs(scry + 136.0f) < 1.0f) 1983 { 1984 the_hero.energy = min(the_hero.energy, (the_hero.y + 144.0f)/10.0f*100.0f); 1985 if (the_hero.energy <= 0.0) 1986 { 1987 the_hero.die("Pressure"); 1988 } 1989 } 1990 1991 // Location: The mine 1992 if (abs(scrx - 330.0f) < 1.0f && abs(scry + 34.0f) < 1.0f && 1993 grasshopper_item.inventory && bird.fly == 0) 1994 { 1995 bird.start_fly(); 1996 track = 2; 1997 music_start_tick = cast(long)SDL_GetTicks(); 1998 play_music(); 1999 } 2000 2001 float oldscrx = scrx, oldscry = scry; 2002 2003 while (the_hero.x-scrx > 15.0) 2004 { 2005 scrx += 30.0; 2006 } 2007 2008 while (the_hero.x-scrx < -15.0) 2009 { 2010 scrx -= 30.0; 2011 } 2012 2013 while (the_hero.y-scry > 8.5) 2014 { 2015 scry += 17.0; 2016 } 2017 2018 while (the_hero.y-scry < -8.5) 2019 { 2020 scry -= 17.0; 2021 } 2022 2023 if ( abs(scrx - 510.0) < 1.0 && abs(scry + 153.0) < 1.0 ) 2024 { 2025 the_hero.force_dx = -0.15; 2026 the_hero.dy = the_hero.JUMP_V; 2027 if (the_hero.lives < 0) the_hero.lives = 0; 2028 state = state.TO_BE_CONTINUED_MESSAGE; 2029 scrx -= 30.0; 2030 } 2031 2032 sc = SC(cast(int)round(scrx/30), cast(int)round(scry/17)); 2033 if (sc !in screen_names) 2034 { 2035 scrx = oldscrx; 2036 scry = oldscry; 2037 } 2038 2039 if ( (oldscrx != scrx || oldscry != scry) && 2040 abs(scrx - 15*30.0) < 1.0 && abs(scry + 7*17.0) < 1.0 && 2041 track == 4 && 2042 all_items_in_the_castle() && rope.in_the_castle() ) 2043 { 2044 track = 3; 2045 music_start_tick = cast(long)SDL_GetTicks(); 2046 play_music(); 2047 } 2048 2049 if (oldscrx != scrx || oldscry!=scry) 2050 { 2051 sl_tid.send(cast(int) round(scrx/30.0), 2052 cast(int) round(scry/17.0)); 2053 } 2054 2055 if (explosure.frame >= 0 && abs(scrx - 420.0) < 1.0 && 2056 abs(scry - 0.0) < 1.0) 2057 { 2058 dizzy_live_after_explosure_quest_state = 1; 2059 } 2060 2061 if (wait_meteorite < 0 && "Martian_Agronomist_Gives_Bucket" in done_dialogs && 2062 oldscrx < 149 && scrx > 149) 2063 { 2064 wait_meteorite = 0; 2065 } 2066 2067 if (wait_meteorite2 < 0 && bird.x < 170.0) 2068 { 2069 wait_meteorite2 = 0; 2070 } 2071 2072 if (bucket_of_water.inventory && abs(scrx - 360.0) < 1.0 && 2073 abs(scry - 0.0) < 1.0) 2074 { 2075 foreach(i, ref item_num; inventory) 2076 { 2077 if (items[item_num] == bucket_of_water) 2078 { 2079 bucket_of_water.inventory = false; 2080 bucket_of_water.used = true; 2081 bucket_of_ice.inventory = true; 2082 bucket_of_ice.used = false; 2083 item_num++; 2084 break; 2085 } 2086 } 2087 } 2088 } 2089 2090 return true; 2091 } 2092 2093 void print_message(TEMP_MESSAGES msg, string str = null) 2094 { 2095 temp_message = msg; 2096 temp_message_str = str; 2097 temp_message_frame_from = frame; 2098 temp_message_frame_to = frame+200; 2099 } 2100 2101 void pause(GlobalState gs) 2102 { 2103 paused = !paused; 2104 } 2105 2106 void 2107 process_event(GlobalState gs, SDL_Event event) 2108 { 2109 2110 } 2111 2112 void 2113 quit(GlobalState gs) 2114 { 2115 gs.stopGame(); 2116 } 2117 2118 void 2119 start_left(GlobalState gs) 2120 { 2121 if (!(keys & LEFT_KEY)) 2122 { 2123 keys |= LEFT_KEY; 2124 the_hero.start_left(gs); 2125 } 2126 } 2127 2128 void stop_left(GlobalState gs) 2129 { 2130 if (keys & LEFT_KEY) 2131 { 2132 keys &= ~LEFT_KEY; 2133 the_hero.stop_left(gs); 2134 } 2135 } 2136 2137 void 2138 start_right(GlobalState gs) 2139 { 2140 if (!(keys & RIGHT_KEY)) 2141 { 2142 keys |= RIGHT_KEY; 2143 the_hero.start_right(gs); 2144 } 2145 } 2146 2147 void stop_right(GlobalState gs) 2148 { 2149 if (keys & RIGHT_KEY) 2150 { 2151 keys &= ~RIGHT_KEY; 2152 the_hero.stop_right(gs); 2153 } 2154 } 2155 2156 void start_jump(GlobalState gs) 2157 { 2158 if (state == STATE.INVENTORY) 2159 { 2160 inv_num--; 2161 if (inv_num < -1) inv_num = cast(int)(inventory.length-1); 2162 } 2163 else if (!(keys & UP_KEY)) 2164 { 2165 the_hero.start_jump(gs); 2166 } 2167 2168 keys |= UP_KEY; 2169 } 2170 2171 void stop_jump(GlobalState gs) 2172 { 2173 keys &= ~UP_KEY; 2174 } 2175 2176 void down(GlobalState gs) 2177 { 2178 if (state == STATE.INVENTORY) 2179 { 2180 inv_num++; 2181 if (inv_num >= inventory.length) inv_num = -1; 2182 } 2183 keys |= DOWN_KEY; 2184 } 2185 2186 void stop_down(GlobalState gs) 2187 { 2188 keys &= ~DOWN_KEY; 2189 } 2190 2191 void change_language(GlobalState gs) 2192 { 2193 lang++; 2194 if (lang > LANG.MAX) lang = LANG.EN; 2195 } 2196 2197 void print_coords(GlobalState gs) 2198 { 2199 writefln("x=%s, y=%s, z=%s", the_hero.x, the_hero.y, the_hero.z); 2200 } 2201 2202 void switch_slow(GlobalState gs) 2203 { 2204 if (keys & CTRL_KEY) return save(gs); 2205 if (slow >= 0) slow = -1; 2206 else slow = 0; 2207 } 2208 2209 void switch_sensors(GlobalState gs) 2210 { 2211 the_hero.show_sensors = !the_hero.show_sensors; 2212 } 2213 2214 void ctrl_down(GlobalState gs) 2215 { 2216 keys |= CTRL_KEY; 2217 } 2218 2219 void ctrl_up(GlobalState gs) 2220 { 2221 keys &= ~CTRL_KEY; 2222 } 2223 2224 void shift_down(GlobalState gs) 2225 { 2226 keys |= SHIFT_KEY; 2227 } 2228 2229 void shift_up(GlobalState gs) 2230 { 2231 keys &= ~SHIFT_KEY; 2232 } 2233 2234 void action(GlobalState gs) 2235 { 2236 switch_label: 2237 final switch(state) 2238 { 2239 case STATE.NO_DIALOGS: 2240 2241 foreach(i, star; stars) 2242 { 2243 if (star.maybe_taken(gs, the_hero)) 2244 { 2245 state = STATE.ENERGY_STAR; 2246 num_stars++; 2247 the_hero.energy += 25.0; 2248 if (the_hero.energy > 100.0) 2249 { 2250 the_hero.energy = 100.0; 2251 if (energy == 100.0) energy = 99.0; 2252 } 2253 star.take(); 2254 break switch_label; 2255 } 2256 } 2257 2258 if (bag.maybe_taken(gs, the_hero)) 2259 { 2260 max_items = 5; 2261 bag.used = true; 2262 state = STATE.BAG_FOUND; 2263 break switch_label; 2264 } 2265 2266 bool stone_place = abs(the_hero.x-242.6) < 3.0 && 2267 abs(the_hero.y+5.0) < 0.5; 2268 bool stone_in_inventory = stone_place && (stone1.inventory || stone2.inventory); 2269 bool bug_place = abs(the_hero.x-242.6) < 3.0 && 2270 abs(the_hero.y+5.0) < 0.5; 2271 2272 foreach(i, ref item; items) 2273 { 2274 if (item.maybe_taken(gs, the_hero) && 2275 (item.model != "stone1" && 2276 item.model != "stone2" || !stone_in_inventory)) 2277 { 2278 if (inventory.length >= max_items) 2279 { 2280 state = STATE.TOO_MANY_ITEMS; 2281 break switch_label; 2282 } 2283 2284 inventory ~= i; 2285 item.inventory = true; 2286 2287 state = STATE.INVENTORY; 2288 inv_num = -1; 2289 break switch_label; 2290 } 2291 } 2292 2293 // Location: Martian-Agronomist 2294 if (abs(the_hero.x-282.25) < 2.6 && abs(the_hero.y-0.95) < 0.5 && !the_hero.jump) 2295 { 2296 if ("Martian_Agronomist_Hello" !in done_dialogs) 2297 { 2298 done_dialogs["Martian_Agronomist_Hello"] = true; 2299 state = STATE.MARTIAN_AGRONOMIST_HELLO; 2300 break switch_label; 2301 } 2302 2303 if (dizzy_throw_branch_quest_state >= 5 && 2304 "Martian_Agronomist_Rope" !in done_dialogs) 2305 { 2306 done_dialogs["Martian_Agronomist_Rope"] = true; 2307 state = STATE.MARTIAN_AGRONOMIST_ROPE; 2308 break switch_label; 2309 } 2310 2311 if ("Martian_Chemist_Hello" in done_dialogs && 2312 "Martian_Agronomist_Gives_Bucket" !in done_dialogs) 2313 { 2314 done_dialogs["Martian_Agronomist_Gives_Bucket"] = true; 2315 state = STATE.MARTIAN_AGRONOMIST_GIVES_BUCKET; 2316 break switch_label; 2317 } 2318 2319 if (dizzy_water_flowers_state == 1 && 2320 "Martian_Agronomist_Thanks" !in done_dialogs) 2321 { 2322 done_dialogs["Martian_Agronomist_Thanks"] = true; 2323 state = STATE.MARTIAN_AGRONOMIST_THANKS; 2324 break switch_label; 2325 } 2326 } 2327 2328 // Location: Martian-Engineer 2329 if (abs(the_hero.x-402.0) < 2.6 && abs(the_hero.y-2.7) < 0.5 && !the_hero.jump) 2330 { 2331 if ("Martian_Agronomist_Thanks" in done_dialogs && 2332 "Martian_Engineer_Returns_Player" !in done_dialogs) 2333 { 2334 done_dialogs["Martian_Engineer_Returns_Player"] = true; 2335 state = STATE.MARTIAN_ENGINEER_RETURNS_PLAYER; 2336 break switch_label; 2337 } 2338 2339 if ((light_branch.inventory || 2340 light_branch.def_x != light_branch.x || 2341 light_branch.def_y != light_branch.y) && 2342 "Martian_Engineer_Gives_Spade" !in done_dialogs) 2343 { 2344 done_dialogs["Martian_Engineer_Gives_Spade"] = true; 2345 state = STATE.MARTIAN_ENGINEER_GIVES_SPADE; 2346 break switch_label; 2347 } 2348 2349 if (squid_item.used && bird_item.used && 2350 "Martian_Engineer_Returns_Bucket" !in done_dialogs) 2351 { 2352 done_dialogs["Martian_Engineer_Returns_Bucket"] = true; 2353 state = STATE.MARTIAN_ENGINEER_RETURNS_BUCKET; 2354 break switch_label; 2355 } 2356 2357 if (bug.sprayed && grasshopper.sprayed && 2358 whistle.def_x == whistle.x && 2359 whistle.def_y == whistle.y) 2360 { 2361 state = STATE.MARTIAN_ENGINEER_GIVES_WHISTLE; 2362 break switch_label; 2363 } 2364 } 2365 2366 // Location: Door in the cave of light tree (Outdoor) 2367 if (key.used && abs(the_hero.x-16.5) < 1.5 && abs(the_hero.y-0.7) < 0.5 && !the_hero.jump) 2368 { 2369 the_hero.y = 26.8; 2370 break switch_label; 2371 } 2372 2373 // Location: Door in the cave of light tree (Indoor) 2374 if (abs(the_hero.x-16.5) < 1.5 && abs(the_hero.y-26.8) < 0.5 && !the_hero.jump) 2375 { 2376 the_hero.y = 0.7; 2377 break switch_label; 2378 } 2379 2380 // Location: Door in the undercave (Outdoor) 2381 if (abs(the_hero.x-36.2) < 1.5 && abs(the_hero.y-34.9) < 0.5 && !the_hero.jump) 2382 { 2383 the_hero.y = 68.9; 2384 break switch_label; 2385 } 2386 2387 // Location: Door in the undercave (Indoor) 2388 if (abs(the_hero.x-36.2) < 1.5 && abs(the_hero.y-68.9) < 0.5 && !the_hero.jump) 2389 { 2390 the_hero.y = 34.9; 2391 break switch_label; 2392 } 2393 2394 // Location: Door of bam (Outdoor) 2395 if (abs(the_hero.x-311.5) < 1.5 && abs(the_hero.y+0.1) < 0.5 && !the_hero.jump) 2396 { 2397 the_hero.x = 304.7; 2398 the_hero.y = 26.2; 2399 bag_bug_anim.start(); 2400 break switch_label; 2401 } 2402 2403 // Location: Door of bam (Indoor) 2404 if (abs(the_hero.x-304.7) < 1.5 && abs(the_hero.y-26.2) < 0.5 && !the_hero.jump) 2405 { 2406 the_hero.x = 311.5; 2407 the_hero.y = -0.1; 2408 break switch_label; 2409 } 2410 2411 // Location: Booth (Outdoor) 2412 if (abs(the_hero.x-308.7) < 1.5 && abs(the_hero.y+6.2) < 0.5 && !the_hero.jump) 2413 { 2414 state = STATE.LOOKING_BOOTH_MESSAGE; 2415 break switch_label; 2416 } 2417 2418 // Location : near branch under tree 2419 if (dizzy_used_knife_quest_state == 2 && 2420 abs(the_hero.x-327.0) < 1.5 && abs(the_hero.y+6.0) < 0.5 && !the_hero.jump) 2421 { 2422 if (inventory.length >= max_items) 2423 { 2424 state = STATE.TOO_MANY_ITEMS; 2425 break switch_label; 2426 } 2427 2428 foreach(i, ref item; items) 2429 { 2430 if (item.model == "branch") 2431 { 2432 dizzy_used_knife_quest_state++; 2433 2434 inventory ~= i; 2435 item.inventory = true; 2436 break; 2437 } 2438 } 2439 } 2440 2441 // Location : Danger sign in the muzzle of volcano 2442 if (rope_state == 1 && 2443 abs(the_hero.x-418.1) < 1.5 && 2444 abs(the_hero.y-1.0) < 0.5 && !the_hero.jump) 2445 { 2446 foreach(i, ref item; items) 2447 { 2448 if (item.model == "rope") 2449 { 2450 if (inventory.length >= max_items) 2451 { 2452 state = STATE.TOO_MANY_ITEMS; 2453 break switch_label; 2454 } 2455 2456 state = STATE.DIZZY_UNTIED_ROPE_MESSAGE; 2457 inventory ~= i; 2458 item.inventory = true; 2459 item.used = false; 2460 2461 break switch_label; 2462 } 2463 } 2464 } 2465 2466 // Location : Danger sign before Martian-Agronomist 2467 if (rope_state == 2 && 2468 abs(the_hero.x-245.0) < 1.5 && 2469 abs(the_hero.y-2.0) < 0.5 && !the_hero.jump) 2470 { 2471 foreach(i, ref item; items) 2472 { 2473 if (item.model == "rope") 2474 { 2475 if (inventory.length >= max_items) 2476 { 2477 state = STATE.TOO_MANY_ITEMS; 2478 break switch_label; 2479 } 2480 2481 state = STATE.DIZZY_UNTIED_ROPE_MESSAGE; 2482 inventory ~= i; 2483 item.inventory = true; 2484 item.used = false; 2485 2486 break switch_label; 2487 } 2488 } 2489 } 2490 2491 // Location : Danger sign underground 2492 if (rope_state == 3 && 2493 abs(the_hero.x-331.2) < 1.5 && 2494 abs(the_hero.y+14.0) < 0.5 && !the_hero.jump) 2495 { 2496 foreach(i, ref item; items) 2497 { 2498 if (item.model == "rope") 2499 { 2500 if (inventory.length >= max_items) 2501 { 2502 state = STATE.TOO_MANY_ITEMS; 2503 break switch_label; 2504 } 2505 2506 state = STATE.DIZZY_UNTIED_ROPE_MESSAGE; 2507 inventory ~= i; 2508 item.inventory = true; 2509 item.used = false; 2510 2511 break switch_label; 2512 } 2513 } 2514 } 2515 2516 // Location : Near tree with the dog, rope 2517 if (dizzy_cuts_rope_quest_state >= 0 && 2518 dizzy_throw_branch_quest_state >= 5 && 2519 dog.hidden == 1 && 2520 short_rope.x == short_rope.def_x && 2521 short_rope.y == short_rope.def_y && 2522 abs(the_hero.x-359.2) < 1.5 && abs(the_hero.y+5.0) < 0.5 && !the_hero.jump) 2523 { 2524 foreach(i, ref item; items) 2525 { 2526 if (item.model == "short-rope") 2527 { 2528 if (inventory.length >= max_items) 2529 { 2530 state = STATE.TOO_MANY_ITEMS; 2531 break switch_label; 2532 } 2533 2534 state = STATE.DIZZY_UNTIED_SHORT_ROPE_MESSAGE; 2535 inventory ~= i; 2536 item.inventory = true; 2537 item.used = false; 2538 dog.hide(); 2539 2540 break switch_label; 2541 } 2542 } 2543 } 2544 2545 // Location: Martian-Chemist 2546 if (abs(the_hero.x-463.2) < 2.6 && abs(the_hero.y-1.7) < 0.5 && !the_hero.jump) 2547 { 2548 if ("Martian_Chemist_Hello" !in done_dialogs) 2549 { 2550 done_dialogs["Martian_Chemist_Hello"] = true; 2551 state = STATE.MARTIAN_CHEMIST_HELLO; 2552 break switch_label; 2553 } 2554 } 2555 2556 // Location : Cave with grasshopper 2557 if (ground_cave.frame >= 0 && 2558 !grasshopper.killed && 2559 grasshopper.y < 62.4 && 2560 abs(grasshopper.x-30.3) < 2.0 && 2561 abs(the_hero.x-30.3) < 3.0 && 2562 abs(the_hero.y-62.7) < 0.5 && !the_hero.jump) 2563 { 2564 foreach(i, ref item; items) 2565 { 2566 if (item.model == "grasshopper-0") 2567 { 2568 if (inventory.length >= max_items) 2569 { 2570 state = STATE.TOO_MANY_ITEMS; 2571 break switch_label; 2572 } 2573 2574 state = STATE.DIZZY_CATCH_GRASSHOPPER_MESSAGE; 2575 inventory ~= i; 2576 item.inventory = true; 2577 item.used = false; 2578 grasshopper.kill(); 2579 break switch_label; 2580 } 2581 } 2582 } 2583 2584 state = STATE.INVENTORY; 2585 inv_num = -1; 2586 break; 2587 case STATE.INVENTORY: 2588 if (inv_num >= 0) 2589 { 2590 // Location : On Tree 2591 if (items[inventory[inv_num]].model == "kitchen-knife" && 2592 abs(the_hero.x-327.0) < 1.5 && abs(the_hero.y-2.3) < 0.5 && !the_hero.jump) 2593 { 2594 state = STATE.DIZZY_USED_KNIFE_MESSAGE; 2595 dizzy_used_knife_quest_state = 0; 2596 the_hero.use_knife(); 2597 break switch_label; 2598 } 2599 2600 // Location : Near tree with the dog 2601 if (items[inventory[inv_num]].model == "branch" && 2602 dizzy_throw_branch_quest_state == -1 && 2603 abs(the_hero.x-354.1) < 3 && abs(the_hero.y+5.0) < 0.5 && !the_hero.jump) 2604 { 2605 state = STATE.DIZZY_THROW_BRANCH_MESSAGE; 2606 dizzy_throw_branch_quest_state = 0; 2607 the_hero.throw_branch(); 2608 2609 inventory = inventory[0..inv_num] ~ inventory[inv_num+1..$]; 2610 branch.inventory = false; 2611 branch.used = true; 2612 2613 break switch_label; 2614 } 2615 2616 // Location : Near tree with the dog, rope 2617 if (items[inventory[inv_num]].model == "kitchen-knife" && 2618 dizzy_cuts_rope_quest_state == -1 && 2619 abs(the_hero.x-359.2) < 1.5 && abs(the_hero.y+5.0) < 0.5 && !the_hero.jump) 2620 { 2621 state = STATE.DIZZY_CUTS_ROPE_MESSAGE; 2622 dizzy_cuts_rope_quest_state = 0; 2623 the_hero.cut_rope(); 2624 break switch_label; 2625 } 2626 2627 // Location : Martian-Engineer 2628 if (items[inventory[inv_num]].model == "player" && 2629 "Martian_Engineer_Takes_Player" !in done_dialogs && 2630 abs(the_hero.x-martian_engineer.x) < 4.0 && 2631 abs(the_hero.y-martian_engineer.y) < 0.5 && !the_hero.jump) 2632 { 2633 done_dialogs["Martian_Engineer_Takes_Player"] = true; 2634 state = STATE.MARTIAN_ENGINEER_TAKES_PLAYER; 2635 inventory = inventory[0..inv_num] ~ inventory[inv_num+1..$]; 2636 player.inventory = false; 2637 player.used = true; 2638 2639 break switch_label; 2640 } 2641 if (items[inventory[inv_num]].model == "bucket-of-ice" && 2642 "Martian_Engineer_Returns_Player" in done_dialogs && 2643 "Martian_Engineer_Takes_Bucket" !in done_dialogs && 2644 abs(the_hero.x-402.0) < 2.6 && abs(the_hero.y-2.7) < 0.5 && !the_hero.jump) 2645 { 2646 done_dialogs["Martian_Engineer_Takes_Bucket"] = true; 2647 state = STATE.MARTIAN_ENGINEER_TAKES_BUCKET; 2648 //inventory[inv_num] -= 2; 2649 bucket_of_ice.inventory = false; 2650 bucket_of_ice.used = true; 2651 //bucket.inventory = true; 2652 //bucket.used = false; 2653 inventory = inventory[0..inv_num] ~ inventory[inv_num+1..$]; 2654 2655 break switch_label; 2656 } 2657 2658 if (items[inventory[inv_num]].model == "bucket-of-ice" && 2659 "Martian_Engineer_Returns_Player" in done_dialogs && 2660 abs(the_hero.x-402.0) < 2.6 && abs(the_hero.y-2.7) < 0.5 && !the_hero.jump) 2661 { 2662 done_dialogs["Martian_Engineer_Takes_Bucket"] = true; 2663 state = STATE.MARTIAN_ENGINEER_TAKES_BUCKET; 2664 inventory[inv_num] -= 2; 2665 bucket_of_ice.inventory = false; 2666 bucket_of_ice.used = true; 2667 bucket.inventory = true; 2668 bucket.used = false; 2669 2670 break switch_label; 2671 } 2672 2673 // Location: Martian-Chemist 2674 if (items[inventory[inv_num]].model == "grasshoppers-poison" && 2675 abs(the_hero.x-463.2) < 2.6 && abs(the_hero.y-1.7) < 0.5 && !the_hero.jump) 2676 { 2677 if (!grasshopper_item.inventory || 2678 !bird_item.inventory) 2679 { 2680 state = STATE.MARTIAN_CHEMIST_NO_GRASSHOPPER; 2681 break switch_label; 2682 } 2683 } 2684 if (items[inventory[inv_num]].model == "grasshopper-0" && 2685 abs(the_hero.x-463.2) < 2.6 && abs(the_hero.y-1.7) < 0.5 && !the_hero.jump) 2686 { 2687 if (!grasshoppers_poison.inventory || 2688 !bird_item.inventory) 2689 { 2690 state = STATE.MARTIAN_CHEMIST_NO_BIRD; 2691 break switch_label; 2692 } 2693 } 2694 if (items[inventory[inv_num]].model == "bird-item" && 2695 abs(the_hero.x-463.2) < 2.6 && abs(the_hero.y-1.7) < 0.5 && !the_hero.jump) 2696 { 2697 if (!grasshoppers_poison.inventory || 2698 !grasshopper_item.inventory) 2699 { 2700 state = STATE.MARTIAN_CHEMIST_NO_GRASSHOPPERS_POISON; 2701 break switch_label; 2702 } 2703 } 2704 if ((items[inventory[inv_num]].model == "grasshoppers-poison" || 2705 items[inventory[inv_num]].model == "grasshopper-0" || 2706 items[inventory[inv_num]].model == "bird-item") && 2707 abs(the_hero.x-463.2) < 2.6 && abs(the_hero.y-1.7) < 0.5 && !the_hero.jump) 2708 { 2709 if (grasshoppers_poison.inventory && 2710 grasshopper_item.inventory && 2711 bird_item.inventory) 2712 { 2713 grasshoppers_poison.used = true; 2714 grasshopper_item.used = true; 2715 bird_item.used = true; 2716 2717 size_t[] new_inv; 2718 foreach (inv; inventory) 2719 { 2720 if (items[inv].model != "grasshoppers-poison" && 2721 items[inv].model != "grasshopper-0" && 2722 items[inv].model != "bird-item") 2723 { 2724 new_inv ~= inv; 2725 } 2726 } 2727 inventory = new_inv; 2728 2729 if (!bugs_poison.used) 2730 state = STATE.MARTIAN_CHEMIST_THANK_YOU; 2731 else 2732 state = STATE.MARTIAN_CHEMIST_NEED_WATER_FROM_LIGHT_TREE_CAVE; 2733 break switch_label; 2734 } 2735 } 2736 2737 // Location: Martian-Chemist 2738 if (items[inventory[inv_num]].model == "bugs-poison" && 2739 abs(the_hero.x-463.2) < 2.6 && abs(the_hero.y-1.7) < 0.5 && !the_hero.jump) 2740 { 2741 if (!bug_item.inventory || 2742 !fish_item.inventory || 2743 !squid_item.inventory) 2744 { 2745 state = STATE.MARTIAN_CHEMIST_NO_BUG; 2746 break switch_label; 2747 } 2748 } 2749 if (items[inventory[inv_num]].model == "bug" && 2750 abs(the_hero.x-463.2) < 2.6 && abs(the_hero.y-1.7) < 0.5 && !the_hero.jump) 2751 { 2752 if (!bugs_poison.inventory || 2753 !fish_item.inventory || 2754 !squid_item.inventory) 2755 { 2756 state = STATE.MARTIAN_CHEMIST_NO_FISH; 2757 break switch_label; 2758 } 2759 } 2760 if (items[inventory[inv_num]].model == "fish-item" && 2761 abs(the_hero.x-463.2) < 2.6 && abs(the_hero.y-1.7) < 0.5 && !the_hero.jump) 2762 { 2763 if (!bugs_poison.inventory || 2764 !bug_item.inventory || 2765 !squid_item.inventory) 2766 { 2767 state = STATE.MARTIAN_CHEMIST_NO_SQUID; 2768 break switch_label; 2769 } 2770 } 2771 if (items[inventory[inv_num]].model == "squid-item" && 2772 abs(the_hero.x-463.2) < 2.6 && abs(the_hero.y-1.7) < 0.5 && !the_hero.jump) 2773 { 2774 if (!bugs_poison.inventory || 2775 !bug_item.inventory || 2776 !fish_item.inventory) 2777 { 2778 state = STATE.MARTIAN_CHEMIST_NO_BUGS_POISON; 2779 break switch_label; 2780 } 2781 } 2782 if ((items[inventory[inv_num]].model == "bugs-poison" || 2783 items[inventory[inv_num]].model == "bug" || 2784 items[inventory[inv_num]].model == "fish-item" || 2785 items[inventory[inv_num]].model == "squid-item") && 2786 abs(the_hero.x-463.2) < 2.6 && abs(the_hero.y-1.7) < 0.5 && !the_hero.jump) 2787 { 2788 if (bugs_poison.inventory && 2789 bug_item.inventory && 2790 fish_item.inventory && 2791 squid_item.inventory) 2792 { 2793 bugs_poison.used = true; 2794 bug_item.used = true; 2795 fish_item.used = true; 2796 squid_item.used = true; 2797 2798 size_t[] new_inv; 2799 foreach (inv; inventory) 2800 { 2801 if (items[inv].model != "bugs-poison" && 2802 items[inv].model != "bug" && 2803 items[inv].model != "fish-item" && 2804 items[inv].model != "squid-item") 2805 { 2806 new_inv ~= inv; 2807 } 2808 } 2809 inventory = new_inv; 2810 2811 if (!grasshoppers_poison.used) 2812 state = STATE.MARTIAN_CHEMIST_THANK_YOU; 2813 else 2814 state = STATE.MARTIAN_CHEMIST_NEED_WATER_FROM_LIGHT_TREE_CAVE; 2815 break switch_label; 2816 } 2817 } 2818 2819 // Location: Martian-Chemist 2820 if (items[inventory[inv_num]].model == "bucket-with-light-water" && 2821 abs(the_hero.x-463.2) < 2.6 && abs(the_hero.y-1.7) < 0.5 && !the_hero.jump) 2822 { 2823 state = STATE.MARTIAN_CHEMIST_GIVES_PSYCHOTROPIC_SPRAY; 2824 inventory = inventory[0..inv_num] ~ inventory[inv_num+1..$]; 2825 bucket_with_light_water.inventory = false; 2826 bucket_with_light_water.used = true; 2827 2828 break switch_label; 2829 } 2830 2831 2832 // Location : Danger sign in the muzzle of volcano 2833 if (items[inventory[inv_num]].model == "rope" && 2834 abs(the_hero.x-418.1) < 1.5 && 2835 abs(the_hero.y-1.0) < 0.5 && !the_hero.jump) 2836 { 2837 state = STATE.DIZZY_TIED_ROPE_MESSAGE; 2838 inventory = inventory[0..inv_num] ~ inventory[inv_num+1..$]; 2839 rope.inventory = false; 2840 rope.used = true; 2841 2842 break switch_label; 2843 } 2844 2845 // Location : Danger sign before Martian-Agronomist 2846 if (items[inventory[inv_num]].model == "rope" && 2847 abs(the_hero.x-245.0) < 1.5 && 2848 abs(the_hero.y-2.0) < 0.5 && !the_hero.jump) 2849 { 2850 state = STATE.DIZZY_TIED_ROPE_MESSAGE; 2851 inventory = inventory[0..inv_num] ~ inventory[inv_num+1..$]; 2852 rope.inventory = false; 2853 rope.used = true; 2854 2855 break switch_label; 2856 } 2857 2858 // Location : Danger sign underground 2859 if (items[inventory[inv_num]].model == "rope" && 2860 abs(the_hero.x-331.2) < 1.5 && 2861 abs(the_hero.y+14.0) < 0.5 && !the_hero.jump) 2862 { 2863 state = STATE.DIZZY_TIED_ROPE_MESSAGE; 2864 inventory = inventory[0..inv_num] ~ inventory[inv_num+1..$]; 2865 rope.inventory = false; 2866 rope.used = true; 2867 2868 break switch_label; 2869 } 2870 2871 if (items[inventory[inv_num]].model == "stunning-drink") 2872 { 2873 state = STATE.DIZZY_DRINK_STUNNING_MESSAGE; 2874 break switch_label; 2875 } 2876 2877 // Location : Well 2878 if ((items[inventory[inv_num]].model == "bucket" || 2879 items[inventory[inv_num]].model == "bucket-of-ice") && 2880 rope.inventory && 2881 abs(the_hero.x-118.8) < 1.5 && 2882 abs(the_hero.y+4.1) < 0.5 && !the_hero.jump) 2883 { 2884 if (dizzy_water_flowers_state < 0) 2885 { 2886 state = STATE.DIZZY_TRIES_FILL_BUCKET_MESSAGE; 2887 } 2888 else 2889 { 2890 state = STATE.DIZZY_FILL_BUCKET_MESSAGE; 2891 } 2892 break switch_label; 2893 } 2894 if (items[inventory[inv_num]].model == "meteorite" && 2895 abs(the_hero.x-118.8) < 1.5 && 2896 abs(the_hero.y+4.1) < 0.5 && !the_hero.jump) 2897 { 2898 state = STATE.DIZZY_THROW_METEORITE_MESSAGE; 2899 inventory = inventory[0..inv_num] ~ inventory[inv_num+1..$]; 2900 meteorite.inventory = false; 2901 meteorite.used = true; 2902 dizzy_water_flowers_state = 0; 2903 break switch_label; 2904 } 2905 2906 // Location : Garden of agronomist 2907 if (dizzy_water_flowers_state < 1 && 2908 items[inventory[inv_num]].model == "bucket-of-water" && 2909 abs(the_hero.x-276.0) < 3.0 && 2910 abs(the_hero.y+8.1) < 0.5 && !the_hero.jump) 2911 { 2912 state = STATE.DIZZY_TRIES_WATER_FLOWERS_MESSAGE; 2913 break switch_label; 2914 } 2915 if (dizzy_water_flowers_state < 1 && 2916 items[inventory[inv_num]].model == "bucket-covered" && 2917 abs(the_hero.x-276.0) < 3.0 && 2918 abs(the_hero.y+8.1) < 0.5 && !the_hero.jump) 2919 { 2920 state = STATE.DIZZY_WATER_FLOWERS_MESSAGE; 2921 bucket_covered.inventory = false; 2922 bucket_covered.used = true; 2923 blanket.inventory = true; 2924 blanket.used = false; 2925 inventory[inv_num] += 3; 2926 dizzy_water_flowers_state = 1; 2927 the_hero.water_with_bucket_of_water(); 2928 break switch_label; 2929 } 2930 2931 // Location : Garden under tree 2932 if (ground_garden.frame < 0 && 2933 items[inventory[inv_num]].model == "spade" && 2934 abs(the_hero.x-326.1) < 3.0 && 2935 abs(the_hero.y+6.0) < 0.5 && !the_hero.jump) 2936 { 2937 ground_garden.frame = root.frame; 2938 state = STATE.DIZZY_DIG_MESSAGE; 2939 the_hero.dig(); 2940 break switch_label; 2941 } 2942 2943 // Location : Cave of light tree 2944 if (items[inventory[inv_num]].model == "branch" && 2945 "Martian_Engineer_Takes_Bucket" in done_dialogs && 2946 abs(the_hero.x-12.3) < 1.5 && 2947 abs(the_hero.y+7.3) < 0.5 && !the_hero.jump) 2948 { 2949 state = STATE.DIZZY_HOLD_BRANCH_UNDER_DROP; 2950 branch.inventory = false; 2951 branch.used = true; 2952 light_branch.inventory = true; 2953 light_branch.used = false; 2954 inventory[inv_num]++; 2955 break switch_label; 2956 } 2957 if (items[inventory[inv_num]].model == "bucket" && 2958 "Martian_Engineer_Returns_Bucket" in done_dialogs && 2959 abs(the_hero.x-12.3) < 1.5 && 2960 abs(the_hero.y+7.3) < 0.5 && !the_hero.jump) 2961 { 2962 state = STATE.DIZZY_TRIES_TO_GET_WATER; 2963 break switch_label; 2964 } 2965 if (items[inventory[inv_num]].model == "bucket-with-ground" && 2966 "Martian_Engineer_Returns_Bucket" in done_dialogs && 2967 abs(the_hero.x-12.3) < 1.5 && 2968 abs(the_hero.y+7.3) < 0.5 && !the_hero.jump) 2969 { 2970 state = STATE.DIZZY_GET_LIGHT_WATER; 2971 foreach(i, ref item; items) 2972 { 2973 if (item.model == "bucket-with-light-water") 2974 { 2975 items[inventory[inv_num]].inventory = false; 2976 items[inventory[inv_num]].used = true; 2977 inventory[inv_num] = i; 2978 item.inventory = true; 2979 break; 2980 } 2981 } 2982 break switch_label; 2983 } 2984 2985 // Location : Door in the cave of light tree 2986 if (items[inventory[inv_num]].model == "key" && 2987 abs(the_hero.x-16.8) < 1.5 && 2988 abs(the_hero.y-0.6) < 0.5 && !the_hero.jump) 2989 { 2990 state = STATE.DIZZY_OPEN_DOOR; 2991 key.inventory = false; 2992 key.used = true; 2993 inventory = inventory[0..inv_num] ~ inventory[inv_num+1..$]; 2994 door.y += 17.0f; 2995 break switch_label; 2996 } 2997 2998 // Location : Cave with grasshopper 2999 if (ground_cave.frame < 0 && 3000 items[inventory[inv_num]].model == "spade" && 3001 abs(the_hero.x-30.3) < 3.0 && 3002 abs(the_hero.y-62.7) < 0.5 && !the_hero.jump) 3003 { 3004 state = STATE.DIZZY_DIG2_MESSAGE; 3005 break switch_label; 3006 } 3007 if (items[inventory[inv_num]].model == "bucket" && 3008 "Martian_Engineer_Returns_Bucket" in done_dialogs && 3009 abs(the_hero.x-30.3) < 1.5 && 3010 abs(the_hero.y-62.7) < 0.5 && !the_hero.jump) 3011 { 3012 state = STATE.DIZZY_PUT_GROUND_TO_THE_BUCKET; 3013 foreach(i, ref item; items) 3014 { 3015 if (item.model == "bucket-with-ground") 3016 { 3017 items[inventory[inv_num]].inventory = false; 3018 items[inventory[inv_num]].used = true; 3019 inventory[inv_num] = i; 3020 item.inventory = true; 3021 break; 3022 } 3023 } 3024 break switch_label; 3025 } 3026 3027 // Location : The Castle, near Zaks 3028 if (ground_castle.frame < 0 && 3029 items[inventory[inv_num]].model == "spade" && 3030 abs(the_hero.x-476.0) < 3.0 && 3031 abs(the_hero.y+159.0) < 0.5 && !the_hero.jump) 3032 { 3033 state = STATE.DIZZY_DIG3_MESSAGE; 3034 break switch_label; 3035 } 3036 3037 // Location : The Castle, near Zaks, in the shelter 3038 if (ground_castle.frame >= 0 && 3039 items[inventory[inv_num]].model == "whistle" && 3040 abs(the_hero.x-473.9) < 3.0 && 3041 abs(the_hero.y+159.5) < 0.5 && !the_hero.jump) 3042 { 3043 if (!all_items_in_the_castle()) 3044 { 3045 state = STATE.NOT_ALL_ITEMS_IN_THE_CASTLE_MESSAGE; 3046 break switch_label; 3047 } 3048 else if (!rope.in_the_castle()) 3049 { 3050 state = STATE.ROPE_NOT_IN_THE_CASTLE_MESSAGE; 3051 break switch_label; 3052 } 3053 else 3054 { 3055 state = STATE.DIZZY_WHISTLE_MESSAGE; 3056 inventory = inventory[0..inv_num] ~ inventory[inv_num+1..$]; 3057 whistle.inventory = false; 3058 whistle.used = true; 3059 break switch_label; 3060 } 3061 } 3062 3063 // Location : The bug place 3064 if ((items[inventory[inv_num]].model == "stone1" || 3065 items[inventory[inv_num]].model == "stone2") && 3066 abs(the_hero.x-242.6) < 3.0 && 3067 abs(the_hero.y+5.0) < 0.5 && !the_hero.jump) 3068 { 3069 state = STATE.DIZZY_PUT_STONE_MESSAGE; 3070 3071 if ( !stone1.inventory && abs(stone1.x - 242.6) < 0.1 && abs(stone1.y + 5.2) < 0.1 || 3072 !stone2.inventory && abs(stone2.x - 242.6) < 0.1 && abs(stone2.y + 5.2) < 0.1 ) 3073 { 3074 items[inventory[inv_num]].inventory = false; 3075 items[inventory[inv_num]].x = 242.6; 3076 items[inventory[inv_num]].y = -4.4; 3077 items[inventory[inv_num]].z = the_hero.z; 3078 inventory = inventory[0..inv_num]~ inventory[inv_num+1..$]; 3079 } 3080 else 3081 { 3082 items[inventory[inv_num]].inventory = false; 3083 items[inventory[inv_num]].x = 242.6; 3084 items[inventory[inv_num]].y = -5.2; 3085 items[inventory[inv_num]].z = the_hero.z; 3086 inventory = inventory[0..inv_num]~ inventory[inv_num+1..$]; 3087 } 3088 3089 break switch_label; 3090 } 3091 3092 // Location : Lair of shallow habitats 3093 if (items[inventory[inv_num]].model == "fish-rod" && 3094 bug_item.inventory && 3095 abs(the_hero.x-371.5) < 1.5 && 3096 abs(the_hero.y+104.8) < 0.5 && !the_hero.jump) 3097 { 3098 state = STATE.DIZZY_CATCH_FISH_MESSAGE; 3099 3100 foreach(i, ref item; items) 3101 { 3102 if (item.model == "fish-item") 3103 { 3104 items[inventory[inv_num]].inventory = false; 3105 items[inventory[inv_num]].used = true; 3106 inventory[inv_num] = i; 3107 item.inventory = true; 3108 fish.hide(); 3109 break; 3110 } 3111 } 3112 3113 break switch_label; 3114 } 3115 3116 // Location : Lair of deep-sea dweller 3117 if (items[inventory[inv_num]].model == "short-rope" && 3118 fish_item.inventory && 3119 abs(the_hero.x-274.0) < 4.0 && 3120 abs(the_hero.y+122.0) < 6.0) 3121 { 3122 state = STATE.DIZZY_CATCH_SQUID_MESSAGE; 3123 3124 foreach(i, ref item; items) 3125 { 3126 if (item.model == "squid-item") 3127 { 3128 items[inventory[inv_num]].inventory = false; 3129 items[inventory[inv_num]].used = true; 3130 inventory[inv_num] = i; 3131 item.inventory = true; 3132 squid.hide(); 3133 break; 3134 } 3135 } 3136 3137 break switch_label; 3138 } 3139 3140 // Location: Near bug 3141 if (items[inventory[inv_num]].model == "nettle" && 3142 abs(the_hero.x-bug.x) < 3.0 && 3143 abs(the_hero.y-bug.y) < 0.5 && !the_hero.jump) 3144 { 3145 if ( (!stone1.inventory && abs(stone1.x - 242.6) < 0.1 && abs(stone1.y + 4.4) < 0.1 || 3146 !stone2.inventory && abs(stone2.x - 242.6) < 0.1 && abs(stone2.y + 4.4) < 0.1) && 3147 bug.x < 242.6 ) 3148 { 3149 state = STATE.DIZZY_CATCH_BUG_MESSAGE; 3150 3151 foreach(i, ref item; items) 3152 { 3153 if (item.model == "bug") 3154 { 3155 items[inventory[inv_num]].inventory = false; 3156 items[inventory[inv_num]].used = true; 3157 inventory[inv_num] = i; 3158 item.inventory = true; 3159 bug.kill(); 3160 break; 3161 } 3162 } 3163 } 3164 else 3165 { 3166 state = STATE.DIZZY_TRY_CATCH_BUG_MESSAGE; 3167 } 3168 3169 break switch_label; 3170 } 3171 3172 // Location: Near bug 3173 if (items[inventory[inv_num]].model == "psychotropic-spray" && 3174 !bug.sprayed && 3175 abs(the_hero.x-bug.x) < 3.0 && 3176 abs(the_hero.y-bug.y) < 0.5 && !the_hero.jump) 3177 { 3178 state = STATE.DIZZY_SPRAYED_BUG_MESSAGE; 3179 bug.spray(); 3180 3181 break switch_label; 3182 } 3183 3184 // Location: Near grasshopper 3185 if (items[inventory[inv_num]].model == "psychotropic-spray" && 3186 !grasshopper.sprayed && 3187 abs(the_hero.x-grasshopper.x) < 3.0 && 3188 abs(the_hero.y-grasshopper.y) < 0.5 && !the_hero.jump) 3189 { 3190 state = STATE.DIZZY_SPRAYED_GRASSHOPPER_MESSAGE; 3191 grasshopper.spray(); 3192 3193 break switch_label; 3194 } 3195 3196 if (dizzy_water_flowers_state < 1 && 3197 items[inventory[inv_num]].model == "blanket" && 3198 bucket_of_water.inventory) 3199 { 3200 state = STATE.DIZZY_COVERED_BUCKET_MESSAGE; 3201 break switch_label; 3202 } 3203 3204 items[inventory[inv_num]].inventory = false; 3205 items[inventory[inv_num]].x = the_hero.x; 3206 items[inventory[inv_num]].y = the_hero.y; 3207 items[inventory[inv_num]].z = the_hero.z; 3208 inventory = inventory[0..inv_num]~ inventory[inv_num+1..$]; 3209 } 3210 state = STATE.NO_DIALOGS; 3211 break; 3212 case STATE.ENERGY_STAR: 3213 case STATE.TOO_MANY_ITEMS: 3214 case STATE.MARTIAN_AGRONOMIST_HELLO6: 3215 case STATE.DIZZY_TRIES_FILL_BUCKET_MESSAGE: 3216 case STATE.DIZZY_THROW_METEORITE_MESSAGE: 3217 case STATE.MARTIAN_AGRONOMIST_THANKS: 3218 case STATE.MARTIAN_ENGINEER_TAKES_BUCKET1: 3219 case STATE.DIZZY_HOLD_BRANCH_UNDER_DROP: 3220 case STATE.DIZZY_OPEN_DOOR: 3221 case STATE.BAG_FOUND: 3222 case STATE.DIZZY_CATCH_GRASSHOPPER_MESSAGE: 3223 case STATE.MARTIAN_CHEMIST_NO_GRASSHOPPER: 3224 case STATE.MARTIAN_CHEMIST_NO_BIRD: 3225 case STATE.MARTIAN_CHEMIST_NO_GRASSHOPPERS_POISON: 3226 case STATE.MARTIAN_CHEMIST_NO_BUG: 3227 case STATE.MARTIAN_CHEMIST_NO_FISH: 3228 case STATE.MARTIAN_CHEMIST_NO_SQUID: 3229 case STATE.MARTIAN_CHEMIST_NO_BUGS_POISON: 3230 case STATE.MARTIAN_CHEMIST_THANK_YOU: 3231 case STATE.MARTIAN_CHEMIST_NEED_WATER_FROM_LIGHT_TREE_CAVE: 3232 case STATE.DIZZY_PUT_STONE_MESSAGE: 3233 case STATE.DIZZY_TRY_CATCH_BUG_MESSAGE: 3234 case STATE.DIZZY_CATCH_BUG_MESSAGE: 3235 case STATE.DIZZY_UNTIED_SHORT_ROPE_MESSAGE: 3236 case STATE.DIZZY_CATCH_FISH_MESSAGE: 3237 case STATE.DIZZY_CATCH_SQUID_MESSAGE: 3238 case STATE.DIZZY_TRIES_TO_GET_WATER: 3239 case STATE.DIZZY_PUT_GROUND_TO_THE_BUCKET: 3240 case STATE.DIZZY_GET_LIGHT_WATER: 3241 case STATE.DIZZY_SPRAYED_BUG_MESSAGE: 3242 case STATE.DIZZY_SPRAYED_GRASSHOPPER_MESSAGE: 3243 case STATE.NOT_ALL_ITEMS_IN_THE_CASTLE_MESSAGE: 3244 case STATE.ROPE_NOT_IN_THE_CASTLE_MESSAGE: 3245 case STATE.TO_BE_CONTINUED_MESSAGE: 3246 state = STATE.NO_DIALOGS; 3247 break; 3248 case STATE.PIERCED_BY_STALAGMITE: 3249 case STATE.PIERCED_BY_STALACTITE: 3250 case STATE.HIT_BY_METEORITE: 3251 case STATE.DISSOLVED_IN_ACID: 3252 case STATE.BURNED_IN_LAVA: 3253 case STATE.DAMAGED_BY_PIN: 3254 case STATE.HIT_BY_ROCK: 3255 case STATE.BURNED_IN_FLAME: 3256 case STATE.CRUSHED_BY_PRESSURE: 3257 if ( abs(scrx-420.0) < 1.0 && 3258 (abs(scry+17.0) < 1.0 || abs(scry-0.0) < 1.0) ) 3259 { 3260 if (dizzy_live_after_explosure_quest_state < 0) 3261 { 3262 if (baloon.inventory) 3263 { 3264 foreach(i, item_num; inventory) 3265 { 3266 if (items[item_num] == baloon) 3267 { 3268 inventory = inventory[0..i] ~ inventory[i+1..$]; 3269 break; 3270 } 3271 } 3272 } 3273 3274 baloon.load(null); 3275 explosure.load(null); 3276 } 3277 the_hero.last_safe = [418.1, 1.0, 0.0]; 3278 } 3279 the_hero.rise(); 3280 state = STATE.NO_DIALOGS; 3281 break; 3282 case STATE.MARTIAN_AGRONOMIST_HELLO: 3283 case STATE.MARTIAN_AGRONOMIST_HELLO1: 3284 case STATE.MARTIAN_AGRONOMIST_HELLO2: 3285 case STATE.MARTIAN_AGRONOMIST_HELLO3: 3286 case STATE.MARTIAN_AGRONOMIST_HELLO4: 3287 case STATE.MARTIAN_AGRONOMIST_HELLO5: 3288 case STATE.MARTIAN_CHEMIST_HELLO: 3289 case STATE.MARTIAN_CHEMIST_HELLO1: 3290 case STATE.MARTIAN_CHEMIST_HELLO2: 3291 case STATE.MARTIAN_CHEMIST_HELLO3: 3292 case STATE.MARTIAN_CHEMIST_HELLO4: 3293 case STATE.DIZZY_USED_KNIFE_MESSAGE: 3294 case STATE.DIZZY_THROW_BRANCH_MESSAGE: 3295 case STATE.DIZZY_CUTS_ROPE_MESSAGE: 3296 case STATE.MARTIAN_AGRONOMIST_GIVES_BUCKET: 3297 case STATE.MARTIAN_ENGINEER_RETURNS_PLAYER: 3298 case STATE.MARTIAN_ENGINEER_RETURNS_PLAYER1: 3299 case STATE.MARTIAN_ENGINEER_TAKES_BUCKET: 3300 case STATE.DIZZY_DIG_MESSAGE: 3301 case STATE.ZAKS_SAYS_FAREWELL_WORD: 3302 state++; 3303 break; 3304 case STATE.DIZZY_WHISTLE_MESSAGE: 3305 things_sweep_away_zaks.unhide(); 3306 state++; 3307 break; 3308 case STATE.THINGS_SWEEP_AWAY_ZAKS_ANIM: 3309 things_sweep_away_zaks.hide(); 3310 stones.frame = frame; 3311 stones.tick(gs); 3312 stone3.x = 413.4; 3313 stone3.y = -84.3; 3314 state++; 3315 break; 3316 case STATE.LOOKING_BOOTH_MESSAGE: 3317 state = STATE.LOOKING_BOOTH; 3318 scry += 68.0; 3319 sl_tid.send(cast(int) round(scrx/30.0), 3320 cast(int) round(scry/17.0)); 3321 break; 3322 case STATE.LOOKING_BOOTH: 3323 scry -= 68.0; 3324 state = STATE.NO_DIALOGS; 3325 sl_tid.send(cast(int) round(scrx/30.0), 3326 cast(int) round(scry/17.0)); 3327 break; 3328 case STATE.DIZZY_USED_KNIFE_ANIM: 3329 dizzy_used_knife_quest_state = 2; 3330 the_hero.y = -6.0; 3331 the_hero.reset_anim(); 3332 collision_objects["solid"].remove("BranchForBreak"); 3333 state = STATE.NO_DIALOGS; 3334 break; 3335 case STATE.DIZZY_THROW_BRANCH_ANIM: 3336 case STATE.DIZZY_CUTS_ROPE_ANIM: 3337 case STATE.DIZZY_DIG_ANIM: 3338 case STATE.HELP: 3339 break; 3340 case STATE.DIZZY_DIG2_MESSAGE: 3341 ground_cave.frame = frame; 3342 grasshopper.change_solid(true); 3343 state = STATE.NO_DIALOGS; 3344 break; 3345 case STATE.DIZZY_DIG3_MESSAGE: 3346 ground_castle.frame = frame; 3347 state = STATE.NO_DIALOGS; 3348 break; 3349 case STATE.MARTIAN_ENGINEER_GET_AWAY: 3350 if (player.x == player.def_x && 3351 player.y == player.def_y) 3352 { 3353 player.x = 118.0; 3354 player.y = 0.4; 3355 } 3356 the_hero.force_dx = -0.15; 3357 the_hero.dy = the_hero.JUMP_V; 3358 state = STATE.NO_DIALOGS; 3359 break; 3360 case STATE.MARTIAN_AGRONOMIST_ROPE: 3361 rope.x = 280.9; 3362 rope.y = 0.8; 3363 state = STATE.NO_DIALOGS; 3364 break; 3365 case STATE.MARTIAN_AGRONOMIST_GIVES_BUCKET1: 3366 bucket.x = 280.9; 3367 bucket.y = 0.8; 3368 state = STATE.NO_DIALOGS; 3369 break; 3370 case STATE.MARTIAN_ENGINEER_TAKES_PLAYER: 3371 martian_engineer.degrees = 0; 3372 martian_engineer.z = 2.0; 3373 state = STATE.NO_DIALOGS; 3374 break; 3375 case STATE.DIZZY_TIED_ROPE_MESSAGE: 3376 if (abs(scrx - 420.0) < 1.0 && 3377 abs(scry - 0.0) < 1.0) 3378 { 3379 rope_state = 1; 3380 rope1.reinit(); 3381 } 3382 3383 if (abs(scrx - 240.0) < 1.0 && 3384 abs(scry - 0.0) < 1.0) 3385 { 3386 rope_state = 2; 3387 rope2.reinit(); 3388 } 3389 3390 if (abs(scrx - 330.0) < 1.0 && 3391 abs(scry + 17.0) < 1.0) 3392 { 3393 if (pressprot.x == pressprot.def_x && 3394 pressprot.y == pressprot.def_y) 3395 { 3396 pressprot.x = 465.9; 3397 pressprot.y = -6.2; 3398 } 3399 3400 rope_state = 3; 3401 rope3.reinit(); 3402 } 3403 3404 state = STATE.NO_DIALOGS; 3405 break; 3406 3407 case STATE.DIZZY_UNTIED_ROPE_MESSAGE: 3408 rope_state = 0; 3409 state = STATE.NO_DIALOGS; 3410 break; 3411 3412 case STATE.MARTIAN_CHEMIST_HELLO5: 3413 stunning_drink.x = 462.0; 3414 stunning_drink.y = 1.7; 3415 stunning_drink.z = 0.0; 3416 state = STATE.NO_DIALOGS; 3417 break; 3418 3419 case STATE.DIZZY_DRINK_STUNNING_MESSAGE: 3420 foreach(i, ref item_num; inventory) 3421 { 3422 if (items[item_num] == stunning_drink) 3423 { 3424 stunning_drink.used = true; 3425 bottle.inventory = true; 3426 item_num++; 3427 break; 3428 } 3429 } 3430 the_hero.stunning = 10*6000; 3431 state = STATE.NO_DIALOGS; 3432 break; 3433 3434 case STATE.DIZZY_FILL_BUCKET_MESSAGE: 3435 foreach(i, ref item_num; inventory) 3436 { 3437 if (items[item_num] == bucket) 3438 { 3439 bucket.inventory = false; 3440 bucket.used = true; 3441 bucket_of_water.used = false; 3442 bucket_of_water.inventory = true; 3443 item_num++; 3444 break; 3445 } 3446 if (items[item_num] == bucket_of_ice) 3447 { 3448 bucket_of_ice.inventory = false; 3449 bucket_of_ice.used = true; 3450 bucket_of_water.used = false; 3451 bucket_of_water.inventory = true; 3452 item_num--; 3453 break; 3454 } 3455 } 3456 state = STATE.NO_DIALOGS; 3457 break; 3458 3459 case STATE.DIZZY_TRIES_WATER_FLOWERS_MESSAGE: 3460 foreach(i, ref item_num; inventory) 3461 { 3462 if (items[item_num] == bucket_of_water) 3463 { 3464 bucket_of_water.inventory = false; 3465 bucket_of_water.used = true; 3466 bucket_of_ice.inventory = true; 3467 bucket_of_ice.used = false; 3468 item_num++; 3469 break; 3470 } 3471 } 3472 state = STATE.NO_DIALOGS; 3473 break; 3474 3475 case STATE.DIZZY_COVERED_BUCKET_MESSAGE: 3476 foreach(i, ref item_num; inventory) 3477 { 3478 if (items[item_num] == bucket_of_water) 3479 { 3480 bucket_of_water.inventory = false; 3481 bucket_of_water.used = true; 3482 bucket_covered.inventory = true; 3483 bucket_covered.used = false; 3484 item_num += 2; 3485 break; 3486 } 3487 } 3488 3489 foreach(i, ref item_num; inventory) 3490 { 3491 if (items[item_num] == blanket) 3492 { 3493 blanket.inventory = false; 3494 blanket.used = true; 3495 inventory = inventory[0..i] ~ inventory[i+1..$]; 3496 break; 3497 } 3498 } 3499 3500 state = STATE.NO_DIALOGS; 3501 break; 3502 3503 case STATE.DIZZY_WATER_FLOWERS_MESSAGE: 3504 bucket.used = false; 3505 bucket.x = the_hero.x; 3506 bucket.y = the_hero.y; 3507 bucket.z = the_hero.z; 3508 3509 the_hero.reset_anim(); 3510 state = STATE.NO_DIALOGS; 3511 break; 3512 3513 case STATE.MARTIAN_ENGINEER_RETURNS_PLAYER2: 3514 player.used = false; 3515 player.x = the_hero.x - 2.0; 3516 player.y = the_hero.y; 3517 player.z = the_hero.z; 3518 3519 state = STATE.NO_DIALOGS; 3520 break; 3521 3522 case STATE.MARTIAN_ENGINEER_GIVES_SPADE: 3523 spade.used = false; 3524 spade.x = the_hero.x - 2.0; 3525 spade.y = the_hero.y; 3526 spade.z = the_hero.z; 3527 3528 state = STATE.NO_DIALOGS; 3529 break; 3530 3531 case STATE.MARTIAN_ENGINEER_GIVES_WHISTLE: 3532 whistle.used = false; 3533 whistle.x = the_hero.x - 2.0; 3534 whistle.y = the_hero.y; 3535 whistle.z = the_hero.z; 3536 3537 state = STATE.NO_DIALOGS; 3538 break; 3539 3540 case STATE.MARTIAN_ENGINEER_RETURNS_BUCKET: 3541 bucket.used = false; 3542 bucket.x = the_hero.x - 2.0; 3543 bucket.y = the_hero.y; 3544 bucket.z = the_hero.z; 3545 3546 state = STATE.NO_DIALOGS; 3547 break; 3548 3549 case STATE.MARTIAN_CHEMIST_GIVES_PSYCHOTROPIC_SPRAY: 3550 psychotropic_spray.used = false; 3551 psychotropic_spray.x = the_hero.x - 2.0; 3552 psychotropic_spray.y = the_hero.y; 3553 psychotropic_spray.z = the_hero.z; 3554 3555 bucket.used = false; 3556 bucket.x = the_hero.x - 4.0; 3557 bucket.y = the_hero.y; 3558 bucket.z = the_hero.z; 3559 3560 bug.killed = false; 3561 grasshopper.killed = false; 3562 grasshopper.change_solid(false); 3563 3564 track = 4; 3565 music_start_tick = cast(long)SDL_GetTicks(); 3566 play_music(); 3567 3568 state = STATE.NO_DIALOGS; 3569 break; 3570 3571 case STATE.STONES_CRASHES_MESSAGE: 3572 zaks.y -= 17.0; 3573 3574 track = 0; 3575 music_start_tick = cast(long)SDL_GetTicks(); 3576 play_music(); 3577 3578 state = STATE.NO_DIALOGS; 3579 break; 3580 } 3581 } 3582 3583 void load(string[string] s) 3584 { 3585 if ("frame" in s) 3586 frame = s["frame"].to!(long); 3587 else 3588 frame = 0; 3589 3590 temp_message_frame_from = 0; 3591 temp_message_frame_to = 0; 3592 3593 if ("lang" in s) 3594 lang = s["lang"].to!(LANG); 3595 else 3596 lang = LANG.EN; 3597 3598 if ("track" in s) 3599 { 3600 int tr = s["track"].to!(int); 3601 if (track != tr) 3602 { 3603 track = tr; 3604 play_music(); 3605 } 3606 } 3607 else 3608 { 3609 if (track != 0) 3610 { 3611 track = 0; 3612 play_music(); 3613 } 3614 } 3615 3616 num_stars = 0; 3617 foreach(star; stars) 3618 { 3619 star.load(s); 3620 if (star.taken) 3621 num_stars++; 3622 } 3623 3624 inventory = []; 3625 foreach(i, item; items) 3626 { 3627 item.load(s); 3628 if (item.inventory) 3629 inventory ~= i; 3630 } 3631 3632 max_items = (bag.used ? 5 : 3); 3633 3634 foreach(animation; animations) 3635 animation.load(s); 3636 3637 the_hero.load(s); 3638 bag_bug_anim.load(s); 3639 3640 done_dialogs = null; 3641 foreach(d; ["Martian_Agronomist_Hello", 3642 "Martian_Agronomist_Rope", 3643 "Martian_Engineer_Takes_Player", 3644 "Martian_Chemist_Hello", 3645 "Martian_Agronomist_Gives_Bucket", 3646 "Martian_Agronomist_Thanks", 3647 "Martian_Engineer_Returns_Player", 3648 "Martian_Engineer_Takes_Bucket", 3649 "Martian_Engineer_Gives_Spade", 3650 "Martian_Engineer_Returns_Bucket",]) 3651 { 3652 if ("dialog"~d in s) 3653 { 3654 done_dialogs[d] = true; 3655 } 3656 } 3657 3658 if ("dizzy_used_knife" in s) 3659 { 3660 dizzy_used_knife_quest_state = s["dizzy_used_knife"].to!(int); 3661 collision_objects["solid"]["BranchForBreak"] = null; 3662 collision_objects["solid"].remove("BranchForBreak"); 3663 reset_collision_cache(); 3664 } 3665 else 3666 { 3667 dizzy_used_knife_quest_state = -1; 3668 collision_objects["solid"]["BranchForBreak"] = collision_objects["temp-solid"]["BranchForBreak"]; 3669 reset_collision_cache(); 3670 } 3671 3672 if ("dizzy_cuts_rope" in s) 3673 { 3674 dizzy_cuts_rope_quest_state = 0; 3675 dizzy_throw_branch_quest_state = 5; 3676 } 3677 else 3678 { 3679 dizzy_cuts_rope_quest_state = -1; 3680 dizzy_throw_branch_quest_state = -1; 3681 } 3682 3683 if ("dizzy_live_after_explosure" in s) 3684 { 3685 dizzy_live_after_explosure_quest_state = 0; 3686 } 3687 else 3688 dizzy_live_after_explosure_quest_state = -1; 3689 3690 if ("rope_state" in s) 3691 rope_state = s["rope_state"].to!(int); 3692 else rope_state = 0; 3693 3694 if ("dizzy_fields_garden" in s) 3695 dizzy_water_flowers_state = s["dizzy_fields_garden"].to!(int); 3696 else if ("dizzy_water_flowers" in s) 3697 dizzy_water_flowers_state = s["dizzy_water_flowers"].to!(int); 3698 else dizzy_water_flowers_state = -1; 3699 3700 if (meteorite.x != meteorite.def_x || 3701 meteorite.y != meteorite.def_y) 3702 wait_meteorite = 2; 3703 else 3704 wait_meteorite = -1; 3705 3706 if (bird.fly == 2) 3707 wait_meteorite2 = 2; 3708 else 3709 wait_meteorite2 = -1; 3710 } 3711 3712 void save(ref string[string] s) 3713 { 3714 foreach(star; stars) 3715 star.save(s); 3716 3717 foreach(item; items) 3718 item.save(s); 3719 3720 foreach(animation; animations) 3721 animation.save(s); 3722 3723 the_hero.save(s); 3724 bag_bug_anim.save(s); 3725 3726 foreach(d; ["Martian_Agronomist_Hello", 3727 "Martian_Agronomist_Rope", 3728 "Martian_Engineer_Takes_Player", 3729 "Martian_Chemist_Hello", 3730 "Martian_Agronomist_Gives_Bucket", 3731 "Martian_Agronomist_Thanks", 3732 "Martian_Engineer_Returns_Player", 3733 "Martian_Engineer_Takes_Bucket", 3734 "Martian_Engineer_Gives_Spade", 3735 "Martian_Engineer_Returns_Bucket",]) 3736 { 3737 if (d in done_dialogs) 3738 { 3739 s["dialog"~d] = "done"; 3740 } 3741 } 3742 3743 if (dizzy_used_knife_quest_state >= 2) 3744 s["dizzy_used_knife"] = dizzy_used_knife_quest_state.to!(string); 3745 3746 if (dizzy_cuts_rope_quest_state >= 0 && 3747 dizzy_throw_branch_quest_state >= 5) 3748 s["dizzy_cuts_rope"] = "Done"; 3749 3750 if (dizzy_live_after_explosure_quest_state >= 0) 3751 s["dizzy_live_after_explosure"] = "Done"; 3752 3753 if (rope_state != 0) 3754 s["rope_state"] = rope_state.to!(string); 3755 3756 if (dizzy_water_flowers_state >= 0) 3757 s["dizzy_water_flowers"] = dizzy_water_flowers_state.to!(string); 3758 3759 s["frame"] = frame.to!(string); 3760 s["lang"] = lang.to!(string); 3761 s["track"] = track.to!(string); 3762 } 3763 3764 void restart(GlobalState gs) 3765 { 3766 if (!(keys & CTRL_KEY)) return; 3767 3768 load(cast(string[string]) null); 3769 } 3770 3771 void load(GlobalState gs) 3772 { 3773 if (!(keys & CTRL_KEY)) return; 3774 if (state != STATE.NO_DIALOGS) return; 3775 3776 auto s = .load(); 3777 load(s); 3778 } 3779 3780 void save(GlobalState gs) 3781 { 3782 if (keys & (LEFT_KEY | RIGHT_KEY)) 3783 { 3784 print_message(TEMP_MESSAGES.CANT_SAVE_IN_THE_MOVING); 3785 return; 3786 } 3787 3788 if (dizzy_throw_branch_quest_state >= 0 && dizzy_cuts_rope_quest_state < 0 || 3789 dizzy_throw_branch_quest_state < 5 && dizzy_cuts_rope_quest_state >= 0) 3790 { 3791 print_message(TEMP_MESSAGES.CANT_SAVE_DURING_THE_QUEST); 3792 return; 3793 } 3794 3795 if (the_hero.lives < 0) 3796 { 3797 print_message(TEMP_MESSAGES.NEGATIVE_LIVES); 3798 return; 3799 } 3800 3801 if (state != STATE.NO_DIALOGS) return; 3802 3803 string[string] s; 3804 save(s); 3805 .save(s); 3806 3807 print_message(TEMP_MESSAGES.SAVED); 3808 } 3809 3810 void help(GlobalState gs) 3811 { 3812 if (state == STATE.HELP) state = STATE.NO_DIALOGS; 3813 else if (state == STATE.NO_DIALOGS) state = STATE.HELP; 3814 } 3815 3816 void play_music() 3817 { 3818 if (music) 3819 { 3820 if (Mix_PlayMusic(musics[track], -1) == -1) 3821 { 3822 writefln("Mix_PlayMusic: %s", 3823 Mix_GetError().to!(string)()); 3824 } 3825 3826 if(Mix_SetMusicPosition(( 3827 (SDL_GetTicks() - music_start_tick)/1000.0)% 3828 music_len[track]) == -1) { 3829 writefln("Mix_SetMusicPosition: %s\n", 3830 Mix_GetError().to!(string)()); 3831 } 3832 3833 print_message(TEMP_MESSAGES.PLAYS, " "~music_name[track]); 3834 } 3835 else 3836 { 3837 Mix_HaltMusic(); 3838 } 3839 } 3840 3841 void turn_music(GlobalState gs) 3842 { 3843 music = !music; 3844 play_music(); 3845 } 3846 3847 void turn_sounds(GlobalState gs) 3848 { 3849 the_hero.sounds = !the_hero.sounds; 3850 3851 if (!the_hero.sounds) 3852 { 3853 Mix_HaltChannel(-1); 3854 } 3855 } 3856 3857 void 3858 setup_keybar(GlobalState gs) 3859 { 3860 gs.keybar.handlers.clear(); 3861 gs.keybar.handlers_down.clear(); 3862 gs.keybar.handlers_double.clear(); 3863 3864 gs.keybar.handlers_down[SDL_SCANCODE_Q] = KeyHandler(&quit, ("Quit"), "exit.png"); 3865 gs.keybar.handlers_down[SDL_SCANCODE_PRINTSCREEN] = KeyHandler(toDelegate(&make_screenshot), ("Make screenshot"), "Prt Sc"); 3866 gs.keybar.handlers_down[SDL_SCANCODE_P] = KeyHandler(toDelegate(&pause), ("Pause"), "Pause"); 3867 3868 gs.keybar.handlers_down[SDL_SCANCODE_LEFT] = KeyHandler(&start_left, ("Left"), "Left"); 3869 gs.keybar.handlers[SDL_SCANCODE_LEFT] = KeyHandler(&stop_left, ("Left"), "Left"); 3870 gs.keybar.handlers_down[SDL_SCANCODE_RIGHT] = KeyHandler(&start_right, ("Right"), "Right"); 3871 gs.keybar.handlers[SDL_SCANCODE_RIGHT] = KeyHandler(&stop_right, ("Right"), "Right"); 3872 gs.keybar.handlers_down[SDL_SCANCODE_UP] = KeyHandler(&start_jump, ("Jump"), "Jump"); 3873 gs.keybar.handlers[SDL_SCANCODE_UP] = KeyHandler(&stop_jump, ("Jump"), "Jump"); 3874 gs.keybar.handlers_down[SDL_SCANCODE_DOWN] = KeyHandler(&down, ("Down"), "Down"); 3875 gs.keybar.handlers[SDL_SCANCODE_DOWN] = KeyHandler(&stop_down, ("Down"), "Down"); 3876 gs.keybar.handlers_down[SDL_SCANCODE_RETURN] = KeyHandler(&action, ("Action"), "Action"); 3877 3878 gs.keybar.handlers_down[SDL_SCANCODE_Z] = KeyHandler(&start_left, ("Left"), "Left"); 3879 gs.keybar.handlers[SDL_SCANCODE_Z] = KeyHandler(&stop_left, ("Left"), "Left"); 3880 gs.keybar.handlers_down[SDL_SCANCODE_X] = KeyHandler(&start_right, ("Right"), "Right"); 3881 gs.keybar.handlers[SDL_SCANCODE_X] = KeyHandler(&stop_right, ("Right"), "Right"); 3882 gs.keybar.handlers_down[SDL_SCANCODE_K] = KeyHandler(&start_jump, ("Jump"), "Jump"); 3883 gs.keybar.handlers[SDL_SCANCODE_K] = KeyHandler(&stop_jump, ("Jump"), "Jump"); 3884 gs.keybar.handlers_down[SDL_SCANCODE_M] = KeyHandler(&down, ("Down"), "Down"); 3885 gs.keybar.handlers[SDL_SCANCODE_M] = KeyHandler(&stop_down, ("Down"), "Down"); 3886 3887 gs.keybar.handlers_down[SDL_SCANCODE_SPACE] = KeyHandler(&start_jump, ("Jump"), "Jump"); 3888 gs.keybar.handlers[SDL_SCANCODE_SPACE] = KeyHandler(&stop_jump, ("Jump"), "Jump"); 3889 3890 gs.keybar.handlers_down[SDL_SCANCODE_LCTRL] = KeyHandler(&ctrl_down, ("Ctrl"), "Ctrl"); 3891 gs.keybar.handlers[SDL_SCANCODE_LCTRL] = KeyHandler(&ctrl_up, ("Ctrl"), "Ctrl"); 3892 gs.keybar.handlers_down[SDL_SCANCODE_LSHIFT] = KeyHandler(&shift_down, ("Shift"), "Shift"); 3893 gs.keybar.handlers[SDL_SCANCODE_LSHIFT] = KeyHandler(&shift_up, ("Shift"), "Shift"); 3894 3895 gs.keybar.handlers_down[SDL_SCANCODE_C] = KeyHandler(&print_coords, ("Print Coords"), "Coords"); 3896 gs.keybar.handlers_down[SDL_SCANCODE_S] = KeyHandler(&switch_slow, ("Switch Slow"), "Slow"); 3897 gs.keybar.handlers_down[SDL_SCANCODE_E] = KeyHandler(&switch_sensors, ("Show Sensors"), "Sensors"); 3898 gs.keybar.handlers_down[SDL_SCANCODE_U] = KeyHandler(&turn_music, ("On/Off Music"), "Music"); 3899 gs.keybar.handlers_down[SDL_SCANCODE_O] = KeyHandler(&turn_sounds, ("On/Off Sounds"), "Sounds"); 3900 3901 gs.keybar.handlers_down[SDL_SCANCODE_ESCAPE] = KeyHandler(&help, ("Help"), "Help"); 3902 3903 gs.keybar.handlers_down[SDL_SCANCODE_1] = KeyHandler(&the_hero.change_costume, ("Change Costume"), "Cost"); 3904 gs.keybar.handlers_down[SDL_SCANCODE_2] = KeyHandler(&change_language, ("Change Language"), "Lang"); 3905 3906 gs.keybar.handlers_down[SDL_SCANCODE_R] = KeyHandler(&restart, ("Restart"), "Restart"); 3907 gs.keybar.handlers_down[SDL_SCANCODE_L] = KeyHandler(&load, ("Load"), "Load"); 3908 } 3909 } 3910